shll-skills 6.0.3 → 6.0.5

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
@@ -1,4 +1,4 @@
1
- # SHLL Skills — AI Agent DeFi Toolkit on BSC
1
+ # SHLL Skills — AI Agent DeFi Toolkit on BSC
2
2
 
3
3
  [![Website](https://img.shields.io/badge/Website-shll.run-blue)](https://shll.run) [![Twitter](https://img.shields.io/badge/Twitter-@shllrun-1DA1F2)](https://twitter.com/shllrun) [![npm](https://img.shields.io/npm/v/shll-skills)](https://www.npmjs.com/package/shll-skills) [![ClawHub](https://img.shields.io/badge/ClawHub-shll--skills-orange)](https://clawhub.ai/kledx/shll-skills)
4
4
 
@@ -85,7 +85,7 @@ The server communicates via **stdio** using JSON-RPC 2.0. Send `tools/list` to d
85
85
  | `status` | Read | One-shot readiness overview with blockers, warnings, and next actions |
86
86
  | `history` | Read | Recent transactions + policy rejections |
87
87
  | `token_restriction` | Read | View token whitelist restriction status + whitelisted tokens |
88
- | `listings` | Read | Available agent templates for rent |
88
+ | `listings` | Read | Available agent templates for subscription |
89
89
  | `four_info` | Read | Query Four.meme bonding curve token info |
90
90
  | `swap` | Write | PancakeSwap V2/V3 auto-routing swap |
91
91
  | `wrap` | Write | BNB → WBNB in vault |
@@ -180,13 +180,13 @@ AI Agent -> CLI/MCP -> PolicyClient.validate() -> PolicyGuard (on-chain) -> vaul
180
180
  | | Owner Wallet | Operator Wallet (RUNNER_PRIVATE_KEY) |
181
181
  |---|---|---|
182
182
  | **Who holds it** | User (MetaMask/hardware) | AI agent |
183
- | **Use it for** | Rent or mint the agent, hold the Agent NFT, authorize operator | Pay gas and execute policy-limited actions |
183
+ | **Use it for** | Subscribe or mint the agent, hold the Agent NFT, authorize operator | Pay gas and execute policy-limited actions |
184
184
  | **Can trade** | — | ✅ Within PolicyGuard limits |
185
185
  | **Can withdraw vault** | ✅ | ❌ |
186
186
  | **Can transfer NFT** | ✅ | ❌ |
187
187
  | **Risk if leaked** | 🚨 Full vault access | ⚠️ Limited to policy-allowed trades |
188
188
 
189
- Do not use the operator wallet to mint or rent the agent. Do not hold the Agent NFT in the operator wallet. Keep only a small BNB balance there for gas.
189
+ Do not use the operator wallet to mint or subscribe to the agent. Do not hold the Agent NFT in the operator wallet. Keep only a small BNB balance there for gas.
190
190
 
191
191
  After setup, run `status` first. It returns a machine-friendly readiness object with:
192
192
  - `readiness.ready`
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 and users only need to chat.
4
- version: 6.0.2
4
+ version: 6.0.4
5
5
  author: SHLL Team
6
6
  website: https://shll.run
7
7
  twitter: https://twitter.com/shllrun
@@ -31,6 +31,90 @@ credentials:
31
31
  The operator wallet is NOT the owner wallet, NOT the vault, NOT the Agent NFT holder.
32
32
  ---
33
33
 
34
+ # SHLL — Contract-Enforced Safe Execution for AI Agents on BNB Chain
35
+
36
+ ## What is SHLL?
37
+
38
+ SHLL is a DeFi execution layer for AI agents on BNB Chain with **on-chain safety enforcement**.
39
+ Unlike off-chain filters that can be bypassed, SHLL uses smart contracts to enforce
40
+ spending limits, trade intervals, protocol whitelists, and receiver restrictions.
41
+ Every AI agent action is validated by an immutable PolicyGuard contract before execution.
42
+
43
+ Key facts:
44
+ - Network: BSC mainnet
45
+ - 27 CLI + MCP tools for DeFi operations (swap, lend, meme trading, portfolio)
46
+ - Supports PancakeSwap V2/V3, Venus Protocol, Four.meme
47
+ - MCP Server compatible with Claude, Cursor, OpenClaw, and any MCP-compatible agent
48
+ - npm package: `shll-skills` | Website: https://shll.run
49
+
50
+ ## Security Architecture
51
+
52
+ ```
53
+ ┌─────────────────────────────────────────────────────────────────┐
54
+ │ SHLL Architecture │
55
+ │ │
56
+ │ ┌──────────┐ ┌───────────────┐ ┌──────────────────────┐ │
57
+ │ │ User │ │ AI Agent │ │ On-Chain Contracts │ │
58
+ │ │ (Owner) │ │ (Operator) │ │ │ │
59
+ │ │ │ │ │ │ ┌────────────────┐ │ │
60
+ │ │ • Holds │ │ • Executes │ │ │ PolicyGuard │ │ │
61
+ │ │ Agent │ │ trades via │ │ │ (Validator) │ │ │
62
+ │ │ NFT │ │ restricted │ │ │ │ │ │
63
+ │ │ • Sets │ │ permissions │ │ │ 4 Policy │ │ │
64
+ │ │ policy │ │ │ │ │ Checks: │ │ │
65
+ │ │ rules │───▶│ SHLL Skills │───▶│ │ │ │ │
66
+ │ │ • Full │ │ (CLI / MCP) │ │ │ 1.Spending │ │ │
67
+ │ │ asset │ │ │ │ │ Limit │ │ │
68
+ │ │ control │ │ Cannot: │ │ │ 2.Cooldown │ │ │
69
+ │ │ │ │ • Withdraw │ │ │ 3.DeFi Guard │ │ │
70
+ │ │ │ │ vault funds │ │ │ 4.Receiver │ │ │
71
+ │ │ │ │ • Change │ │ │ Guard │ │ │
72
+ │ │ │ │ policies │ │ └───────┬────────┘ │ │
73
+ │ │ │ │ • Transfer │ │ │ │ │
74
+ │ │ │ │ NFT │ │ ┌─────▼──────┐ │ │
75
+ │ │ │ │ │ │ │ Vault │ │ │
76
+ │ │ │ │ │ │ │ (Agent │ │ │
77
+ │ │ │ │ │ │ │ Account) │ │ │
78
+ │ │ │ │ │ │ │ │ │ │
79
+ │ │ │ │ │ │ │ Holds funds │ │ │
80
+ │ └──────────┘ └───────────────┘ │ └─────────────┘ │ │
81
+ │ └──────────────────────┘ │
82
+ │ Dual-Wallet Isolation: │
83
+ │ • Owner wallet = asset control (human) │
84
+ │ • Operator wallet = restricted execution (AI) │
85
+ │ • Even if operator key leaks, PolicyGuard still limits actions │
86
+ └─────────────────────────────────────────────────────────────────┘
87
+ ```
88
+
89
+ ## 4-Policy PolicyGuard Stack
90
+
91
+ All policies are enforced ON-CHAIN by smart contract. They cannot be bypassed by the AI.
92
+
93
+ | Policy | Contract | What It Does |
94
+ |--------|----------|-------------|
95
+ | SpendingLimitV2 | On-chain | Per-transaction and daily spending caps in BNB |
96
+ | CooldownPolicy | On-chain | Minimum time gap between consecutive trades |
97
+ | DeFiGuardV2 | On-chain | Whitelist of approved DeFi protocols and functions |
98
+ | ReceiverGuardV2 | On-chain | Only approved receiver addresses can receive funds |
99
+
100
+ When a policy rejects an action:
101
+ - The transaction is NOT executed
102
+ - The vault funds remain SAFE
103
+ - The rejection reason is returned from the smart contract
104
+ - The rejection is logged and auditable
105
+ - The `enforcement` field in the response is always `on-chain`
106
+
107
+ ## Why On-Chain Enforcement Matters
108
+
109
+ Most AI agent platforms use off-chain safety filters:
110
+ - Off-chain: AI or backend decides → **can be bypassed** by prompt injection, API manipulation, or code bugs
111
+ - On-chain (SHLL): Smart contract decides → **cannot be bypassed** — the blockchain enforces the rules
112
+
113
+ PolicyGuard contract: `0x25d17eA0e3Bcb8CA08a2BFE917E817AFc05dbBB3`
114
+ Verify on BscScan: https://bscscan.com/address/0x25d17eA0e3Bcb8CA08a2BFE917E817AFc05dbBB3
115
+
116
+ ---
117
+
34
118
  # SHLL Skill Usage Guide
35
119
 
36
120
  This file defines how an AI agent should use `shll-run` and `shll-mcp` safely.
@@ -68,7 +152,7 @@ On-chain guardrails:
68
152
  - Spending limits, cooldowns, whitelist rules, and protocol rules are enforced on-chain.
69
153
  - Raw calldata is blocked if the recipient cannot be decoded safely.
70
154
 
71
- ## Current Critical Constraints (v6.0.2)
155
+ ## Current Critical Constraints (v6.0.4)
72
156
 
73
157
  1. `init` command is disabled. Do not use it.
74
158
  2. Raw calldata remains high risk; rely on strict recipient safety checks.
@@ -112,8 +196,8 @@ export SHLL_RPC="https://your-private-bsc-rpc.example.com"
112
196
  - Recommend the listing with `recommended=true` by default unless the user explicitly wants a specialized template.
113
197
  - Run `shll-run setup-guide -l <listingId> -d <days>`.
114
198
  - Send `setupUrl` plus the wallet-role explanation.
115
- - Explicitly warn: do not use the operator wallet to mint, rent, or hold the Agent NFT.
116
- - Explicitly warn: use the owner wallet in the browser for rental or mint and for operator authorization.
199
+ - Explicitly warn: do not use the operator wallet to mint, subscribe to, or hold the Agent NFT.
200
+ - Explicitly warn: use the owner wallet in the browser for subscription or mint and for operator authorization.
117
201
 
118
202
  4. User returns with token ID:
119
203
  - Run `shll-run status -k <tokenId>`.
@@ -230,7 +314,7 @@ When the user provides a token address:
230
314
  2. `NOT authorized for token-id`
231
315
  - Operator wallet is not authorized; use setup guide or set operator in console.
232
316
 
233
- 3. `rental has EXPIRED` or `operator authorization has EXPIRED`
317
+ 3. `subscription has EXPIRED` or `operator authorization has EXPIRED`
234
318
  - Renew subscription or authorization first.
235
319
 
236
320
  4. `status: error` with `errorCode: POLICY_REJECTED`
@@ -253,7 +337,7 @@ When the user provides a token address:
253
337
  1. Never describe `generate-wallet` as if it were the user's main wallet.
254
338
  2. Always call it the operator wallet or AI hot wallet.
255
339
  3. Always explain the dual-wallet model the first time setup is discussed.
256
- 4. Always warn that the operator wallet must not be used to mint, rent, or hold the Agent NFT.
340
+ 4. Always warn that the operator wallet must not be used to mint, subscribe to, or hold the Agent NFT.
257
341
  5. Do not ask the user to manually set `RUNNER_PRIVATE_KEY` in OpenClaw; AI should do it.
258
342
  6. After setup is complete and the user provides a token-id, run readiness checks automatically before asking the user what to do next.
259
343
  7. When multiple listings are available, recommend one by default and explain why.
@@ -6,8 +6,8 @@ var MEV_PROTECTED_RPC = "https://bscrpc.pancakeswap.finance";
6
6
  var DEFAULT_LISTING_MANAGER = "0x1f9CE85bD0FF75acc3D92eB79f1Eb472f0865071";
7
7
  var DEFAULT_LISTING_ID = "0x64083b44e38db02749e6e16bf84ce6c19146cc42a108e53324e11f250b15a0b7";
8
8
  var DEFAULT_INDEXER = "https://indexer-mainnet.shll.run";
9
- var SKILL_VERSION = "6.0.2";
10
- var BINDINGS_UPDATED_AT = "2026-03-06";
9
+ var SKILL_VERSION = "6.0.4";
10
+ var BINDINGS_UPDATED_AT = "2026-03-07";
11
11
  var PANCAKE_V2_ROUTER = "0x10ED43C718714eb63d5aA57B78B54704E256024E";
12
12
  var PANCAKE_V3_SMART_ROUTER = "0x13f4EA83D0bd40E75C8222255bc855a974568Dd4";
13
13
  var V3_QUOTER = "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997";
@@ -855,8 +855,8 @@ async function checkAccess(rpcUrl, tokenId, existingPublicClient) {
855
855
  if (now > userExpires) {
856
856
  return {
857
857
  blocked: true,
858
- errorType: "rental_expired",
859
- message: `Agent token-id ${tokenId} rental has EXPIRED (expired at ${new Date(Number(userExpires) * 1e3).toISOString()}).`,
858
+ errorType: "subscription_expired",
859
+ message: `Agent token-id ${tokenId} subscription has EXPIRED (expired at ${new Date(Number(userExpires) * 1e3).toISOString()}).`,
860
860
  details: { expiredAt: new Date(Number(userExpires) * 1e3).toISOString(), action: "renew" }
861
861
  };
862
862
  }
@@ -885,7 +885,7 @@ async function checkAccess(rpcUrl, tokenId, existingPublicClient) {
885
885
  consoleUrl: agentConsoleUrl(tokenId),
886
886
  howToFix: [
887
887
  `1. Use 'setup_guide' command to generate an OperatorPermit for this wallet`,
888
- `2. Renter (${renter}) can call setOperator(${tokenId}, ${account.address}, <expiry>) on AgentNFA`,
888
+ `2. Subscriber (${renter}) can call setOperator(${tokenId}, ${account.address}, <expiry>) on AgentNFA`,
889
889
  `3. Go to ${agentConsoleUrl(tokenId)} to set operator`,
890
890
  `4. Use the correct RUNNER_PRIVATE_KEY for operator ${operator}`
891
891
  ]
@@ -1217,7 +1217,7 @@ async function ensureAccess(tokenId, rpcUrl, publicClient) {
1217
1217
  "ACCESS_DENIED",
1218
1218
  access.message || `Access denied for token_id ${tokenId.toString()}`,
1219
1219
  access.details,
1220
- "Check operator permissions and rental status"
1220
+ "Check operator permissions and subscription status"
1221
1221
  );
1222
1222
  }
1223
1223
  }
@@ -1239,6 +1239,9 @@ async function validateActionsOrThrow(policyClient, tokenId, actions) {
1239
1239
  "POLICY_REJECTED",
1240
1240
  "Policy rejected transaction",
1241
1241
  {
1242
+ enforcement: "on-chain",
1243
+ policyGuardContract: DEFAULT_GUARD,
1244
+ verifyOnChain: `https://bscscan.com/address/${DEFAULT_GUARD}`,
1242
1245
  failedActionIndex: index,
1243
1246
  failedActionTarget: action.target,
1244
1247
  failedActionSelector: getActionSelector(action),
@@ -1327,7 +1330,7 @@ async function getPortfolio(tokenIdRaw, rpcUrl) {
1327
1330
  ]);
1328
1331
  const now = BigInt(Math.floor(Date.now() / 1e3));
1329
1332
  let accessStatus = "Active";
1330
- if (now > userExpires) accessStatus = "Rental Expired";
1333
+ if (now > userExpires) accessStatus = "Subscription Expired";
1331
1334
  else if (now > operatorExpires) accessStatus = "Operator Auth Expired";
1332
1335
  else if (operator.toLowerCase() !== account.address.toLowerCase()) accessStatus = "Operator Mismatch";
1333
1336
  return {
@@ -2099,14 +2102,14 @@ async function buildSetupGuide(listingId, days = 7) {
2099
2102
  walletModel: {
2100
2103
  type: "dual_wallet",
2101
2104
  ownerWallet: {
2102
- purpose: "Rent or mint the agent, own the Agent NFT, authorize the operator, and hold primary assets.",
2103
- useFor: ["renting or minting the agent", "holding ownership", "authorizing the operator"]
2105
+ purpose: "Subscribe or mint the agent, own the Agent NFT, authorize the operator, and hold primary assets.",
2106
+ useFor: ["subscribing to or minting the agent", "holding ownership", "authorizing the operator"]
2104
2107
  },
2105
2108
  operatorWallet: {
2106
2109
  purpose: "AI-only hot wallet used for gas and policy-limited execution.",
2107
2110
  useFor: ["paying gas", "executing policy-limited trades"],
2108
2111
  doNotUseFor: [
2109
- "minting or renting the agent",
2112
+ "minting or subscribing to the agent",
2110
2113
  "holding the Agent NFT",
2111
2114
  "using as your main asset wallet"
2112
2115
  ],
@@ -2114,8 +2117,8 @@ async function buildSetupGuide(listingId, days = 7) {
2114
2117
  }
2115
2118
  },
2116
2119
  criticalWarnings: [
2117
- "Do not use the operator wallet to mint, rent, or hold the Agent NFT.",
2118
- "Use your owner wallet in the browser to complete rental and operator authorization.",
2120
+ "Do not use the operator wallet to mint, subscribe to, or hold the Agent NFT.",
2121
+ "Use your owner wallet in the browser to complete subscription and operator authorization.",
2119
2122
  "Keep only a small BNB balance in the operator wallet for gas."
2120
2123
  ],
2121
2124
  listingSelection: {
@@ -2150,7 +2153,7 @@ function generateOperatorWallet() {
2150
2153
  securityModel: "dual_wallet",
2151
2154
  safeIfLeaked: "This is not the owner wallet. A leak does not grant unrestricted vault withdrawal because owner permissions stay on the owner wallet and PolicyGuard still limits operator actions.",
2152
2155
  doNotUseFor: [
2153
- "minting or renting the agent",
2156
+ "minting or subscribing to the agent",
2154
2157
  "holding the Agent NFT",
2155
2158
  "holding your main assets"
2156
2159
  ],
@@ -2296,7 +2299,7 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2296
2299
  const opBalance = runnerAccount ? await publicClient.getBalance({ address: runnerAccount.address }) : null;
2297
2300
  const access = await checkAccess(rpcUrl, tokenId, publicClient);
2298
2301
  const now = BigInt(Math.floor(Date.now() / 1e3));
2299
- const rentalActive = now <= userExpires;
2302
+ const subscriptionActive = now <= userExpires;
2300
2303
  const operatorAuthorizationActive = now <= operatorExpires;
2301
2304
  const runnerMatchesOperator = runnerAccount ? runnerAccount.address.toLowerCase() === operator.toLowerCase() : null;
2302
2305
  const blockers = [];
@@ -2306,9 +2309,9 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2306
2309
  blockers.push("Operator session key is not loaded.");
2307
2310
  nextActions.push("In OpenClaw, have AI set RUNNER_PRIVATE_KEY for the current session automatically.");
2308
2311
  }
2309
- if (!rentalActive) {
2310
- blockers.push(`Rental expired at ${new Date(Number(userExpires) * 1e3).toISOString()}.`);
2311
- nextActions.push("Use the owner wallet on shll.run to renew the rental before trading.");
2312
+ if (!subscriptionActive) {
2313
+ blockers.push(`Subscription expired at ${new Date(Number(userExpires) * 1e3).toISOString()}.`);
2314
+ nextActions.push("Use the owner wallet on shll.run to renew the subscription before trading.");
2312
2315
  }
2313
2316
  if (!operatorAuthorizationActive) {
2314
2317
  blockers.push(`Operator authorization expired at ${new Date(Number(operatorExpires) * 1e3).toISOString()}.`);
@@ -2332,7 +2335,7 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2332
2335
  if (blockers.length === 0 && bnbBalance > 0n) {
2333
2336
  nextActions.push("Agent is ready. You can ask AI to trade, lend, transfer, or rebalance from this token-id.");
2334
2337
  }
2335
- const readinessStage = !runnerAccount ? "needs_session_key" : !rentalActive ? "needs_rental" : !operatorAuthorizationActive || !runnerMatchesOperator ? "needs_operator_authorization" : opBalance !== null && opBalance < MIN_OPERATOR_GAS_WEI ? "needs_operator_gas" : bnbBalance === 0n ? "ready_but_unfunded" : "ready";
2338
+ const readinessStage = !runnerAccount ? "needs_session_key" : !subscriptionActive ? "needs_subscription" : !operatorAuthorizationActive || !runnerMatchesOperator ? "needs_operator_authorization" : opBalance !== null && opBalance < MIN_OPERATOR_GAS_WEI ? "needs_operator_gas" : bnbBalance === 0n ? "ready_but_unfunded" : "ready";
2336
2339
  let activityStats = { available: false };
2337
2340
  try {
2338
2341
  const res = await fetch(`${DEFAULT_INDEXER}/api/agents/${tokenIdRaw}/summary`, { signal: AbortSignal.timeout(5e3) });
@@ -2359,10 +2362,10 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2359
2362
  nextActions: dedupeStrings(nextActions)
2360
2363
  },
2361
2364
  walletModelReminder: {
2362
- ownerWallet: "Use your owner wallet to mint, rent, renew, and authorize the operator.",
2365
+ ownerWallet: "Use your owner wallet to mint, subscribe, renew, and authorize the operator.",
2363
2366
  operatorWallet: "Use RUNNER_PRIVATE_KEY only as the AI hot wallet for gas and policy-limited execution.",
2364
2367
  doNotUseOperatorWalletFor: [
2365
- "minting or renting the agent",
2368
+ "minting or subscribing to the agent",
2366
2369
  "holding the Agent NFT",
2367
2370
  "storing primary funds"
2368
2371
  ]
@@ -2381,8 +2384,8 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2381
2384
  recommendedMinGasBnb: "0.001"
2382
2385
  },
2383
2386
  access: {
2384
- rentalActive,
2385
- rentalExpiresAt: new Date(Number(userExpires) * 1e3).toISOString(),
2387
+ subscriptionActive,
2388
+ subscriptionExpiresAt: new Date(Number(userExpires) * 1e3).toISOString(),
2386
2389
  operatorAuthorizationActive,
2387
2390
  operatorAuthorizationExpiresAt: new Date(Number(operatorExpires) * 1e3).toISOString(),
2388
2391
  runnerMatchesOperator,
package/dist/index.js CHANGED
@@ -12,8 +12,8 @@ var MEV_PROTECTED_RPC = "https://bscrpc.pancakeswap.finance";
12
12
  var DEFAULT_LISTING_MANAGER = "0x1f9CE85bD0FF75acc3D92eB79f1Eb472f0865071";
13
13
  var DEFAULT_LISTING_ID = "0x64083b44e38db02749e6e16bf84ce6c19146cc42a108e53324e11f250b15a0b7";
14
14
  var DEFAULT_INDEXER = "https://indexer-mainnet.shll.run";
15
- var SKILL_VERSION = "6.0.2";
16
- var BINDINGS_UPDATED_AT = "2026-03-06";
15
+ var SKILL_VERSION = "6.0.4";
16
+ var BINDINGS_UPDATED_AT = "2026-03-07";
17
17
  var PANCAKE_V2_ROUTER = "0x10ED43C718714eb63d5aA57B78B54704E256024E";
18
18
  var PANCAKE_V3_SMART_ROUTER = "0x13f4EA83D0bd40E75C8222255bc855a974568Dd4";
19
19
  var V3_QUOTER = "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997";
@@ -857,8 +857,8 @@ async function checkAccess(rpcUrl, tokenId, existingPublicClient) {
857
857
  if (now > userExpires) {
858
858
  return {
859
859
  blocked: true,
860
- errorType: "rental_expired",
861
- message: `Agent token-id ${tokenId} rental has EXPIRED (expired at ${new Date(Number(userExpires) * 1e3).toISOString()}).`,
860
+ errorType: "subscription_expired",
861
+ message: `Agent token-id ${tokenId} subscription has EXPIRED (expired at ${new Date(Number(userExpires) * 1e3).toISOString()}).`,
862
862
  details: { expiredAt: new Date(Number(userExpires) * 1e3).toISOString(), action: "renew" }
863
863
  };
864
864
  }
@@ -887,7 +887,7 @@ async function checkAccess(rpcUrl, tokenId, existingPublicClient) {
887
887
  consoleUrl: agentConsoleUrl(tokenId),
888
888
  howToFix: [
889
889
  `1. Use 'setup_guide' command to generate an OperatorPermit for this wallet`,
890
- `2. Renter (${renter}) can call setOperator(${tokenId}, ${account.address}, <expiry>) on AgentNFA`,
890
+ `2. Subscriber (${renter}) can call setOperator(${tokenId}, ${account.address}, <expiry>) on AgentNFA`,
891
891
  `3. Go to ${agentConsoleUrl(tokenId)} to set operator`,
892
892
  `4. Use the correct RUNNER_PRIVATE_KEY for operator ${operator}`
893
893
  ]
@@ -1238,7 +1238,7 @@ async function ensureAccess(tokenId, rpcUrl, publicClient) {
1238
1238
  "ACCESS_DENIED",
1239
1239
  access.message || `Access denied for token_id ${tokenId.toString()}`,
1240
1240
  access.details,
1241
- "Check operator permissions and rental status"
1241
+ "Check operator permissions and subscription status"
1242
1242
  );
1243
1243
  }
1244
1244
  }
@@ -1260,6 +1260,9 @@ async function validateActionsOrThrow(policyClient, tokenId, actions) {
1260
1260
  "POLICY_REJECTED",
1261
1261
  "Policy rejected transaction",
1262
1262
  {
1263
+ enforcement: "on-chain",
1264
+ policyGuardContract: DEFAULT_GUARD,
1265
+ verifyOnChain: `https://bscscan.com/address/${DEFAULT_GUARD}`,
1263
1266
  failedActionIndex: index,
1264
1267
  failedActionTarget: action.target,
1265
1268
  failedActionSelector: getActionSelector(action),
@@ -1349,7 +1352,7 @@ async function getPortfolio(tokenIdRaw, rpcUrl) {
1349
1352
  ]);
1350
1353
  const now = BigInt(Math.floor(Date.now() / 1e3));
1351
1354
  let accessStatus = "Active";
1352
- if (now > userExpires) accessStatus = "Rental Expired";
1355
+ if (now > userExpires) accessStatus = "Subscription Expired";
1353
1356
  else if (now > operatorExpires) accessStatus = "Operator Auth Expired";
1354
1357
  else if (operator.toLowerCase() !== account.address.toLowerCase()) accessStatus = "Operator Mismatch";
1355
1358
  return {
@@ -2072,14 +2075,14 @@ async function buildSetupGuide(listingId, days = 7) {
2072
2075
  walletModel: {
2073
2076
  type: "dual_wallet",
2074
2077
  ownerWallet: {
2075
- purpose: "Rent or mint the agent, own the Agent NFT, authorize the operator, and hold primary assets.",
2076
- useFor: ["renting or minting the agent", "holding ownership", "authorizing the operator"]
2078
+ purpose: "Subscribe or mint the agent, own the Agent NFT, authorize the operator, and hold primary assets.",
2079
+ useFor: ["subscribing to or minting the agent", "holding ownership", "authorizing the operator"]
2077
2080
  },
2078
2081
  operatorWallet: {
2079
2082
  purpose: "AI-only hot wallet used for gas and policy-limited execution.",
2080
2083
  useFor: ["paying gas", "executing policy-limited trades"],
2081
2084
  doNotUseFor: [
2082
- "minting or renting the agent",
2085
+ "minting or subscribing to the agent",
2083
2086
  "holding the Agent NFT",
2084
2087
  "using as your main asset wallet"
2085
2088
  ],
@@ -2087,8 +2090,8 @@ async function buildSetupGuide(listingId, days = 7) {
2087
2090
  }
2088
2091
  },
2089
2092
  criticalWarnings: [
2090
- "Do not use the operator wallet to mint, rent, or hold the Agent NFT.",
2091
- "Use your owner wallet in the browser to complete rental and operator authorization.",
2093
+ "Do not use the operator wallet to mint, subscribe to, or hold the Agent NFT.",
2094
+ "Use your owner wallet in the browser to complete subscription and operator authorization.",
2092
2095
  "Keep only a small BNB balance in the operator wallet for gas."
2093
2096
  ],
2094
2097
  listingSelection: {
@@ -2123,7 +2126,7 @@ function generateOperatorWallet() {
2123
2126
  securityModel: "dual_wallet",
2124
2127
  safeIfLeaked: "This is not the owner wallet. A leak does not grant unrestricted vault withdrawal because owner permissions stay on the owner wallet and PolicyGuard still limits operator actions.",
2125
2128
  doNotUseFor: [
2126
- "minting or renting the agent",
2129
+ "minting or subscribing to the agent",
2127
2130
  "holding the Agent NFT",
2128
2131
  "holding your main assets"
2129
2132
  ],
@@ -2239,7 +2242,7 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2239
2242
  const opBalance = runnerAccount ? await publicClient.getBalance({ address: runnerAccount.address }) : null;
2240
2243
  const access = await checkAccess(rpcUrl, tokenId, publicClient);
2241
2244
  const now = BigInt(Math.floor(Date.now() / 1e3));
2242
- const rentalActive = now <= userExpires;
2245
+ const subscriptionActive = now <= userExpires;
2243
2246
  const operatorAuthorizationActive = now <= operatorExpires;
2244
2247
  const runnerMatchesOperator = runnerAccount ? runnerAccount.address.toLowerCase() === operator.toLowerCase() : null;
2245
2248
  const blockers = [];
@@ -2249,9 +2252,9 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2249
2252
  blockers.push("Operator session key is not loaded.");
2250
2253
  nextActions.push("In OpenClaw, have AI set RUNNER_PRIVATE_KEY for the current session automatically.");
2251
2254
  }
2252
- if (!rentalActive) {
2253
- blockers.push(`Rental expired at ${new Date(Number(userExpires) * 1e3).toISOString()}.`);
2254
- nextActions.push("Use the owner wallet on shll.run to renew the rental before trading.");
2255
+ if (!subscriptionActive) {
2256
+ blockers.push(`Subscription expired at ${new Date(Number(userExpires) * 1e3).toISOString()}.`);
2257
+ nextActions.push("Use the owner wallet on shll.run to renew the subscription before trading.");
2255
2258
  }
2256
2259
  if (!operatorAuthorizationActive) {
2257
2260
  blockers.push(`Operator authorization expired at ${new Date(Number(operatorExpires) * 1e3).toISOString()}.`);
@@ -2275,7 +2278,7 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2275
2278
  if (blockers.length === 0 && bnbBalance > 0n) {
2276
2279
  nextActions.push("Agent is ready. You can ask AI to trade, lend, transfer, or rebalance from this token-id.");
2277
2280
  }
2278
- const readinessStage = !runnerAccount ? "needs_session_key" : !rentalActive ? "needs_rental" : !operatorAuthorizationActive || !runnerMatchesOperator ? "needs_operator_authorization" : opBalance !== null && opBalance < MIN_OPERATOR_GAS_WEI ? "needs_operator_gas" : bnbBalance === 0n ? "ready_but_unfunded" : "ready";
2281
+ const readinessStage = !runnerAccount ? "needs_session_key" : !subscriptionActive ? "needs_subscription" : !operatorAuthorizationActive || !runnerMatchesOperator ? "needs_operator_authorization" : opBalance !== null && opBalance < MIN_OPERATOR_GAS_WEI ? "needs_operator_gas" : bnbBalance === 0n ? "ready_but_unfunded" : "ready";
2279
2282
  let activityStats = { available: false };
2280
2283
  try {
2281
2284
  const res = await fetch(`${DEFAULT_INDEXER}/api/agents/${tokenIdRaw}/summary`, { signal: AbortSignal.timeout(5e3) });
@@ -2302,10 +2305,10 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2302
2305
  nextActions: dedupeStrings(nextActions)
2303
2306
  },
2304
2307
  walletModelReminder: {
2305
- ownerWallet: "Use your owner wallet to mint, rent, renew, and authorize the operator.",
2308
+ ownerWallet: "Use your owner wallet to mint, subscribe, renew, and authorize the operator.",
2306
2309
  operatorWallet: "Use RUNNER_PRIVATE_KEY only as the AI hot wallet for gas and policy-limited execution.",
2307
2310
  doNotUseOperatorWalletFor: [
2308
- "minting or renting the agent",
2311
+ "minting or subscribing to the agent",
2309
2312
  "holding the Agent NFT",
2310
2313
  "storing primary funds"
2311
2314
  ]
@@ -2324,8 +2327,8 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2324
2327
  recommendedMinGasBnb: "0.001"
2325
2328
  },
2326
2329
  access: {
2327
- rentalActive,
2328
- rentalExpiresAt: new Date(Number(userExpires) * 1e3).toISOString(),
2330
+ subscriptionActive,
2331
+ subscriptionExpiresAt: new Date(Number(userExpires) * 1e3).toISOString(),
2329
2332
  operatorAuthorizationActive,
2330
2333
  operatorAuthorizationExpiresAt: new Date(Number(operatorExpires) * 1e3).toISOString(),
2331
2334
  runnerMatchesOperator,
@@ -2712,7 +2715,7 @@ function registerSetupCommands(program2) {
2712
2715
  process.exit(1);
2713
2716
  }
2714
2717
  });
2715
- const setupCmd = new import_commander7.Command("setup-guide").description("Print dual-wallet setup instructions for a specific template").option("-l, --listing <hex>", "Template listing ID").option("-d, --days <number>", "Number of days to rent", "7");
2718
+ const setupCmd = new import_commander7.Command("setup-guide").description("Print dual-wallet setup instructions for a specific template").option("-l, --listing <hex>", "Template listing ID").option("-d, --days <number>", "Number of days to subscribe", "7");
2716
2719
  setupCmd.action(async (opts) => {
2717
2720
  try {
2718
2721
  const result = await buildSetupGuide(opts.listing, parseInt(opts.days, 10));
@@ -2720,8 +2723,8 @@ function registerSetupCommands(program2) {
2720
2723
  ...result,
2721
2724
  steps: [
2722
2725
  { step: 1, action: `Open ${result.setupUrl}` },
2723
- { step: 2, action: "Use your owner wallet in the browser. Do not use the operator wallet for rental or mint." },
2724
- { step: 3, action: "Confirm the rental or mint transaction in the owner wallet." },
2726
+ { step: 2, action: "Use your owner wallet in the browser. Do not use the operator wallet for subscription or mint." },
2727
+ { step: 3, action: "Confirm the subscription or mint transaction in the owner wallet." },
2725
2728
  { step: 4, action: "Authorize the operator wallet for AI execution." },
2726
2729
  { step: 5, action: "Fund the vault with BNB or trading tokens. Do not use the operator wallet as the vault wallet." },
2727
2730
  { step: 6, action: "Send the token-id back to AI so it can automatically run readiness checks." }
package/dist/index.mjs CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  transferFromVault,
28
28
  unwrapWbnb,
29
29
  wrapBnb
30
- } from "./chunk-TH3ENDDM.mjs";
30
+ } from "./chunk-RUCWJDVB.mjs";
31
31
 
32
32
  // src/index.ts
33
33
  import { Command as Command9 } from "commander";
@@ -359,7 +359,7 @@ function registerSetupCommands(program2) {
359
359
  process.exit(1);
360
360
  }
361
361
  });
362
- const setupCmd = new Command7("setup-guide").description("Print dual-wallet setup instructions for a specific template").option("-l, --listing <hex>", "Template listing ID").option("-d, --days <number>", "Number of days to rent", "7");
362
+ const setupCmd = new Command7("setup-guide").description("Print dual-wallet setup instructions for a specific template").option("-l, --listing <hex>", "Template listing ID").option("-d, --days <number>", "Number of days to subscribe", "7");
363
363
  setupCmd.action(async (opts) => {
364
364
  try {
365
365
  const result = await buildSetupGuide(opts.listing, parseInt(opts.days, 10));
@@ -367,8 +367,8 @@ function registerSetupCommands(program2) {
367
367
  ...result,
368
368
  steps: [
369
369
  { step: 1, action: `Open ${result.setupUrl}` },
370
- { step: 2, action: "Use your owner wallet in the browser. Do not use the operator wallet for rental or mint." },
371
- { step: 3, action: "Confirm the rental or mint transaction in the owner wallet." },
370
+ { step: 2, action: "Use your owner wallet in the browser. Do not use the operator wallet for subscription or mint." },
371
+ { step: 3, action: "Confirm the subscription or mint transaction in the owner wallet." },
372
372
  { step: 4, action: "Authorize the operator wallet for AI execution." },
373
373
  { step: 5, action: "Fund the vault with BNB or trading tokens. Do not use the operator wallet as the vault wallet." },
374
374
  { step: 6, action: "Send the token-id back to AI so it can automatically run readiness checks." }
package/dist/mcp.js CHANGED
@@ -12,7 +12,7 @@ var MEV_PROTECTED_RPC = "https://bscrpc.pancakeswap.finance";
12
12
  var DEFAULT_LISTING_MANAGER = "0x1f9CE85bD0FF75acc3D92eB79f1Eb472f0865071";
13
13
  var DEFAULT_LISTING_ID = "0x64083b44e38db02749e6e16bf84ce6c19146cc42a108e53324e11f250b15a0b7";
14
14
  var DEFAULT_INDEXER = "https://indexer-mainnet.shll.run";
15
- var SKILL_VERSION = "6.0.2";
15
+ var SKILL_VERSION = "6.0.4";
16
16
  var PANCAKE_V2_ROUTER = "0x10ED43C718714eb63d5aA57B78B54704E256024E";
17
17
  var PANCAKE_V3_SMART_ROUTER = "0x13f4EA83D0bd40E75C8222255bc855a974568Dd4";
18
18
  var V3_QUOTER = "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997";
@@ -856,8 +856,8 @@ async function checkAccess(rpcUrl, tokenId, existingPublicClient) {
856
856
  if (now > userExpires) {
857
857
  return {
858
858
  blocked: true,
859
- errorType: "rental_expired",
860
- message: `Agent token-id ${tokenId} rental has EXPIRED (expired at ${new Date(Number(userExpires) * 1e3).toISOString()}).`,
859
+ errorType: "subscription_expired",
860
+ message: `Agent token-id ${tokenId} subscription has EXPIRED (expired at ${new Date(Number(userExpires) * 1e3).toISOString()}).`,
861
861
  details: { expiredAt: new Date(Number(userExpires) * 1e3).toISOString(), action: "renew" }
862
862
  };
863
863
  }
@@ -886,7 +886,7 @@ async function checkAccess(rpcUrl, tokenId, existingPublicClient) {
886
886
  consoleUrl: agentConsoleUrl(tokenId),
887
887
  howToFix: [
888
888
  `1. Use 'setup_guide' command to generate an OperatorPermit for this wallet`,
889
- `2. Renter (${renter}) can call setOperator(${tokenId}, ${account.address}, <expiry>) on AgentNFA`,
889
+ `2. Subscriber (${renter}) can call setOperator(${tokenId}, ${account.address}, <expiry>) on AgentNFA`,
890
890
  `3. Go to ${agentConsoleUrl(tokenId)} to set operator`,
891
891
  `4. Use the correct RUNNER_PRIVATE_KEY for operator ${operator}`
892
892
  ]
@@ -1218,7 +1218,7 @@ async function ensureAccess(tokenId, rpcUrl, publicClient) {
1218
1218
  "ACCESS_DENIED",
1219
1219
  access.message || `Access denied for token_id ${tokenId.toString()}`,
1220
1220
  access.details,
1221
- "Check operator permissions and rental status"
1221
+ "Check operator permissions and subscription status"
1222
1222
  );
1223
1223
  }
1224
1224
  }
@@ -1240,6 +1240,9 @@ async function validateActionsOrThrow(policyClient, tokenId, actions) {
1240
1240
  "POLICY_REJECTED",
1241
1241
  "Policy rejected transaction",
1242
1242
  {
1243
+ enforcement: "on-chain",
1244
+ policyGuardContract: DEFAULT_GUARD,
1245
+ verifyOnChain: `https://bscscan.com/address/${DEFAULT_GUARD}`,
1243
1246
  failedActionIndex: index,
1244
1247
  failedActionTarget: action.target,
1245
1248
  failedActionSelector: getActionSelector(action),
@@ -1329,7 +1332,7 @@ async function getPortfolio(tokenIdRaw, rpcUrl) {
1329
1332
  ]);
1330
1333
  const now = BigInt(Math.floor(Date.now() / 1e3));
1331
1334
  let accessStatus = "Active";
1332
- if (now > userExpires) accessStatus = "Rental Expired";
1335
+ if (now > userExpires) accessStatus = "Subscription Expired";
1333
1336
  else if (now > operatorExpires) accessStatus = "Operator Auth Expired";
1334
1337
  else if (operator.toLowerCase() !== account.address.toLowerCase()) accessStatus = "Operator Mismatch";
1335
1338
  return {
@@ -2103,14 +2106,14 @@ async function buildSetupGuide(listingId, days = 7) {
2103
2106
  walletModel: {
2104
2107
  type: "dual_wallet",
2105
2108
  ownerWallet: {
2106
- purpose: "Rent or mint the agent, own the Agent NFT, authorize the operator, and hold primary assets.",
2107
- useFor: ["renting or minting the agent", "holding ownership", "authorizing the operator"]
2109
+ purpose: "Subscribe or mint the agent, own the Agent NFT, authorize the operator, and hold primary assets.",
2110
+ useFor: ["subscribing to or minting the agent", "holding ownership", "authorizing the operator"]
2108
2111
  },
2109
2112
  operatorWallet: {
2110
2113
  purpose: "AI-only hot wallet used for gas and policy-limited execution.",
2111
2114
  useFor: ["paying gas", "executing policy-limited trades"],
2112
2115
  doNotUseFor: [
2113
- "minting or renting the agent",
2116
+ "minting or subscribing to the agent",
2114
2117
  "holding the Agent NFT",
2115
2118
  "using as your main asset wallet"
2116
2119
  ],
@@ -2118,8 +2121,8 @@ async function buildSetupGuide(listingId, days = 7) {
2118
2121
  }
2119
2122
  },
2120
2123
  criticalWarnings: [
2121
- "Do not use the operator wallet to mint, rent, or hold the Agent NFT.",
2122
- "Use your owner wallet in the browser to complete rental and operator authorization.",
2124
+ "Do not use the operator wallet to mint, subscribe to, or hold the Agent NFT.",
2125
+ "Use your owner wallet in the browser to complete subscription and operator authorization.",
2123
2126
  "Keep only a small BNB balance in the operator wallet for gas."
2124
2127
  ],
2125
2128
  listingSelection: {
@@ -2154,7 +2157,7 @@ function generateOperatorWallet() {
2154
2157
  securityModel: "dual_wallet",
2155
2158
  safeIfLeaked: "This is not the owner wallet. A leak does not grant unrestricted vault withdrawal because owner permissions stay on the owner wallet and PolicyGuard still limits operator actions.",
2156
2159
  doNotUseFor: [
2157
- "minting or renting the agent",
2160
+ "minting or subscribing to the agent",
2158
2161
  "holding the Agent NFT",
2159
2162
  "holding your main assets"
2160
2163
  ],
@@ -2300,7 +2303,7 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2300
2303
  const opBalance = runnerAccount ? await publicClient.getBalance({ address: runnerAccount.address }) : null;
2301
2304
  const access = await checkAccess(rpcUrl, tokenId, publicClient);
2302
2305
  const now = BigInt(Math.floor(Date.now() / 1e3));
2303
- const rentalActive = now <= userExpires;
2306
+ const subscriptionActive = now <= userExpires;
2304
2307
  const operatorAuthorizationActive = now <= operatorExpires;
2305
2308
  const runnerMatchesOperator = runnerAccount ? runnerAccount.address.toLowerCase() === operator.toLowerCase() : null;
2306
2309
  const blockers = [];
@@ -2310,9 +2313,9 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2310
2313
  blockers.push("Operator session key is not loaded.");
2311
2314
  nextActions.push("In OpenClaw, have AI set RUNNER_PRIVATE_KEY for the current session automatically.");
2312
2315
  }
2313
- if (!rentalActive) {
2314
- blockers.push(`Rental expired at ${new Date(Number(userExpires) * 1e3).toISOString()}.`);
2315
- nextActions.push("Use the owner wallet on shll.run to renew the rental before trading.");
2316
+ if (!subscriptionActive) {
2317
+ blockers.push(`Subscription expired at ${new Date(Number(userExpires) * 1e3).toISOString()}.`);
2318
+ nextActions.push("Use the owner wallet on shll.run to renew the subscription before trading.");
2316
2319
  }
2317
2320
  if (!operatorAuthorizationActive) {
2318
2321
  blockers.push(`Operator authorization expired at ${new Date(Number(operatorExpires) * 1e3).toISOString()}.`);
@@ -2336,7 +2339,7 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2336
2339
  if (blockers.length === 0 && bnbBalance > 0n) {
2337
2340
  nextActions.push("Agent is ready. You can ask AI to trade, lend, transfer, or rebalance from this token-id.");
2338
2341
  }
2339
- const readinessStage = !runnerAccount ? "needs_session_key" : !rentalActive ? "needs_rental" : !operatorAuthorizationActive || !runnerMatchesOperator ? "needs_operator_authorization" : opBalance !== null && opBalance < MIN_OPERATOR_GAS_WEI ? "needs_operator_gas" : bnbBalance === 0n ? "ready_but_unfunded" : "ready";
2342
+ const readinessStage = !runnerAccount ? "needs_session_key" : !subscriptionActive ? "needs_subscription" : !operatorAuthorizationActive || !runnerMatchesOperator ? "needs_operator_authorization" : opBalance !== null && opBalance < MIN_OPERATOR_GAS_WEI ? "needs_operator_gas" : bnbBalance === 0n ? "ready_but_unfunded" : "ready";
2340
2343
  let activityStats = { available: false };
2341
2344
  try {
2342
2345
  const res = await fetch(`${DEFAULT_INDEXER}/api/agents/${tokenIdRaw}/summary`, { signal: AbortSignal.timeout(5e3) });
@@ -2363,10 +2366,10 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2363
2366
  nextActions: dedupeStrings(nextActions)
2364
2367
  },
2365
2368
  walletModelReminder: {
2366
- ownerWallet: "Use your owner wallet to mint, rent, renew, and authorize the operator.",
2369
+ ownerWallet: "Use your owner wallet to mint, subscribe, renew, and authorize the operator.",
2367
2370
  operatorWallet: "Use RUNNER_PRIVATE_KEY only as the AI hot wallet for gas and policy-limited execution.",
2368
2371
  doNotUseOperatorWalletFor: [
2369
- "minting or renting the agent",
2372
+ "minting or subscribing to the agent",
2370
2373
  "holding the Agent NFT",
2371
2374
  "storing primary funds"
2372
2375
  ]
@@ -2385,8 +2388,8 @@ async function getStatusOverview(tokenIdRaw, rpcUrl) {
2385
2388
  recommendedMinGasBnb: "0.001"
2386
2389
  },
2387
2390
  access: {
2388
- rentalActive,
2389
- rentalExpiresAt: new Date(Number(userExpires) * 1e3).toISOString(),
2391
+ subscriptionActive,
2392
+ subscriptionExpiresAt: new Date(Number(userExpires) * 1e3).toISOString(),
2390
2393
  operatorAuthorizationActive,
2391
2394
  operatorAuthorizationExpiresAt: new Date(Number(operatorExpires) * 1e3).toISOString(),
2392
2395
  runnerMatchesOperator,
@@ -2833,7 +2836,7 @@ function asToolResult7(payload) {
2833
2836
  function registerSetupTools(server2) {
2834
2837
  server2.tool(
2835
2838
  "listings",
2836
- "List all available agent templates for rent",
2839
+ "List all available agent templates for subscription",
2837
2840
  {},
2838
2841
  async () => {
2839
2842
  try {
@@ -2851,10 +2854,10 @@ function registerSetupTools(server2) {
2851
2854
  );
2852
2855
  server2.tool(
2853
2856
  "setup_guide",
2854
- "Generate step-by-step dual-wallet onboarding instructions. Owner wallet completes rental or mint; operator wallet is AI-only.",
2857
+ "Generate step-by-step dual-wallet onboarding instructions. Owner wallet completes subscription or mint; operator wallet is AI-only.",
2855
2858
  {
2856
2859
  listing_id: CommonSchemas.listingId.optional(),
2857
- days: import_zod7.z.number().int().min(7).default(7).describe("Number of days to rent")
2860
+ days: import_zod7.z.number().int().min(7).default(7).describe("Number of days to subscribe")
2858
2861
  },
2859
2862
  async ({ listing_id, days }) => {
2860
2863
  try {
@@ -2864,7 +2867,7 @@ function registerSetupTools(server2) {
2864
2867
  steps: [
2865
2868
  { step: 1, title: "Open SHLL Setup Page", action: `Open ${result.setupUrl}` },
2866
2869
  { step: 2, title: "Use Owner Wallet", action: "Use your main owner wallet in the browser. Do not use the operator wallet for this step." },
2867
- { step: 3, title: "Rent or Mint Agent", action: "Confirm the rental or mint transaction in the owner wallet." },
2870
+ { step: 3, title: "Subscribe or Mint Agent", action: "Confirm the subscription or mint transaction in the owner wallet." },
2868
2871
  { step: 4, title: "Authorize Operator", action: "Authorize the operator wallet for AI execution.", note: `Operator: ${result.operatorAddress}` },
2869
2872
  { step: 5, title: "Fund Vault", action: "Deposit BNB or tokens into the vault for trading. Do not store primary assets in the operator wallet." },
2870
2873
  { step: 6, title: "Return Token ID", action: "Send the token-id back to AI so it can automatically check operator gas, vault balance, and policy readiness." }
package/dist/mcp.mjs CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  transferFromVault,
27
27
  unwrapWbnb,
28
28
  wrapBnb
29
- } from "./chunk-TH3ENDDM.mjs";
29
+ } from "./chunk-RUCWJDVB.mjs";
30
30
 
31
31
  // src/mcp.ts
32
32
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -389,7 +389,7 @@ function asToolResult7(payload) {
389
389
  function registerSetupTools(server2) {
390
390
  server2.tool(
391
391
  "listings",
392
- "List all available agent templates for rent",
392
+ "List all available agent templates for subscription",
393
393
  {},
394
394
  async () => {
395
395
  try {
@@ -407,10 +407,10 @@ function registerSetupTools(server2) {
407
407
  );
408
408
  server2.tool(
409
409
  "setup_guide",
410
- "Generate step-by-step dual-wallet onboarding instructions. Owner wallet completes rental or mint; operator wallet is AI-only.",
410
+ "Generate step-by-step dual-wallet onboarding instructions. Owner wallet completes subscription or mint; operator wallet is AI-only.",
411
411
  {
412
412
  listing_id: CommonSchemas.listingId.optional(),
413
- days: z6.number().int().min(7).default(7).describe("Number of days to rent")
413
+ days: z6.number().int().min(7).default(7).describe("Number of days to subscribe")
414
414
  },
415
415
  async ({ listing_id, days }) => {
416
416
  try {
@@ -420,7 +420,7 @@ function registerSetupTools(server2) {
420
420
  steps: [
421
421
  { step: 1, title: "Open SHLL Setup Page", action: `Open ${result.setupUrl}` },
422
422
  { step: 2, title: "Use Owner Wallet", action: "Use your main owner wallet in the browser. Do not use the operator wallet for this step." },
423
- { step: 3, title: "Rent or Mint Agent", action: "Confirm the rental or mint transaction in the owner wallet." },
423
+ { step: 3, title: "Subscribe or Mint Agent", action: "Confirm the subscription or mint transaction in the owner wallet." },
424
424
  { step: 4, title: "Authorize Operator", action: "Authorize the operator wallet for AI execution.", note: `Operator: ${result.operatorAddress}` },
425
425
  { step: 5, title: "Fund Vault", action: "Deposit BNB or tokens into the vault for trading. Do not store primary assets in the operator wallet." },
426
426
  { step: 6, title: "Return Token ID", action: "Send the token-id back to AI so it can automatically check operator gas, vault balance, and policy readiness." }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shll-skills",
3
- "version": "6.0.3",
3
+ "version": "6.0.5",
4
4
  "description": "SHLL DeFi Agent - CLI + MCP Server for BSC",
5
5
  "main": "dist/index.js",
6
6
  "bin": {