shll-skills 5.4.2 → 5.5.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/SKILL.md +14 -1
- package/dist/index.js +322 -0
- package/dist/index.mjs +322 -0
- package/dist/mcp.js +244 -1
- package/dist/mcp.mjs +244 -1
- package/package.json +1 -1
- package/src/index.ts +370 -0
- package/src/mcp.ts +251 -1
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.
|
|
4
|
+
version: 5.5.0
|
|
5
5
|
author: SHLL Team
|
|
6
6
|
website: https://shll.run
|
|
7
7
|
twitter: https://twitter.com/shllrun
|
|
@@ -150,6 +150,8 @@ Examples:
|
|
|
150
150
|
- "Lend 10 USDT on Venus"
|
|
151
151
|
- "How much am I earning on Venus?"
|
|
152
152
|
- "Redeem my USDT from Venus"
|
|
153
|
+
- "Check this Four.meme token: 0xABC..."
|
|
154
|
+
- "Buy 0.01 BNB of tokens on Four.meme"
|
|
153
155
|
|
|
154
156
|
---
|
|
155
157
|
|
|
@@ -183,6 +185,17 @@ Examples:
|
|
|
183
185
|
|
|
184
186
|
Supported lending tokens: **BNB, USDT, USDC, BUSD**
|
|
185
187
|
|
|
188
|
+
### Four.meme Launchpad (Bonding Curve)
|
|
189
|
+
| Command | What it does |
|
|
190
|
+
|---------|-------------|
|
|
191
|
+
| `shll-run four-info --token <ADDR>` | Query token bonding curve info (price, progress, DEX status) |
|
|
192
|
+
| `shll-run four-buy --token <ADDR> -a <BNB> -k <ID>` | Buy tokens on internal bonding curve with BNB |
|
|
193
|
+
| `shll-run four-sell --token <ADDR> -a <TOKENS> -k <ID>` | Sell tokens on internal bonding curve for BNB |
|
|
194
|
+
|
|
195
|
+
**Requires:** FOUR_MEME DeFi Pack enabled on the agent (renter enables via Console > Safety).
|
|
196
|
+
**Slippage:** Default 10% (meme tokens are volatile). Override with `-s <percent>`.
|
|
197
|
+
**Note:** These commands only work while tokens are in bonding curve phase. Once migrated to DEX, use `swap` instead.
|
|
198
|
+
|
|
186
199
|
### Market Data (read-only)
|
|
187
200
|
| Command | What it does |
|
|
188
201
|
|---------|-------------|
|
package/dist/index.js
CHANGED
|
@@ -2275,6 +2275,325 @@ myAgentsCmd.action(async (opts) => {
|
|
|
2275
2275
|
process.exit(1);
|
|
2276
2276
|
}
|
|
2277
2277
|
});
|
|
2278
|
+
var FOUR_MEME_HELPER_V3 = "0xF251F83e40a78868FcfA3FA4599Dad6494E46034";
|
|
2279
|
+
var FOUR_MEME_HELPER_ABI = [
|
|
2280
|
+
{
|
|
2281
|
+
type: "function",
|
|
2282
|
+
name: "getTokenInfo",
|
|
2283
|
+
inputs: [{ name: "token", type: "address" }],
|
|
2284
|
+
outputs: [
|
|
2285
|
+
{ name: "version", type: "uint256" },
|
|
2286
|
+
{ name: "tokenManager", type: "address" },
|
|
2287
|
+
{ name: "quote", type: "address" },
|
|
2288
|
+
{ name: "lastPrice", type: "uint256" },
|
|
2289
|
+
{ name: "tradingFeeRate", type: "uint256" },
|
|
2290
|
+
{ name: "minTradingFee", type: "uint256" },
|
|
2291
|
+
{ name: "launchTime", type: "uint256" },
|
|
2292
|
+
{ name: "offers", type: "uint256" },
|
|
2293
|
+
{ name: "maxOffers", type: "uint256" },
|
|
2294
|
+
{ name: "funds", type: "uint256" },
|
|
2295
|
+
{ name: "maxFunds", type: "uint256" },
|
|
2296
|
+
{ name: "liquidityAdded", type: "bool" }
|
|
2297
|
+
],
|
|
2298
|
+
stateMutability: "view"
|
|
2299
|
+
},
|
|
2300
|
+
{
|
|
2301
|
+
type: "function",
|
|
2302
|
+
name: "tryBuy",
|
|
2303
|
+
inputs: [
|
|
2304
|
+
{ name: "token", type: "address" },
|
|
2305
|
+
{ name: "amount", type: "uint256" },
|
|
2306
|
+
{ name: "funds", type: "uint256" }
|
|
2307
|
+
],
|
|
2308
|
+
outputs: [
|
|
2309
|
+
{ name: "tokenManager", type: "address" },
|
|
2310
|
+
{ name: "quote", type: "address" },
|
|
2311
|
+
{ name: "estimatedAmount", type: "uint256" },
|
|
2312
|
+
{ name: "estimatedCost", type: "uint256" },
|
|
2313
|
+
{ name: "estimatedFee", type: "uint256" },
|
|
2314
|
+
{ name: "amountMsgValue", type: "uint256" },
|
|
2315
|
+
{ name: "amountApproval", type: "uint256" },
|
|
2316
|
+
{ name: "amountFunds", type: "uint256" }
|
|
2317
|
+
],
|
|
2318
|
+
stateMutability: "view"
|
|
2319
|
+
},
|
|
2320
|
+
{
|
|
2321
|
+
type: "function",
|
|
2322
|
+
name: "trySell",
|
|
2323
|
+
inputs: [
|
|
2324
|
+
{ name: "token", type: "address" },
|
|
2325
|
+
{ name: "amount", type: "uint256" }
|
|
2326
|
+
],
|
|
2327
|
+
outputs: [
|
|
2328
|
+
{ name: "tokenManager", type: "address" },
|
|
2329
|
+
{ name: "quote", type: "address" },
|
|
2330
|
+
{ name: "funds", type: "uint256" },
|
|
2331
|
+
{ name: "fee", type: "uint256" }
|
|
2332
|
+
],
|
|
2333
|
+
stateMutability: "view"
|
|
2334
|
+
}
|
|
2335
|
+
];
|
|
2336
|
+
var FOUR_MEME_V1_ABI = [
|
|
2337
|
+
{
|
|
2338
|
+
type: "function",
|
|
2339
|
+
name: "purchaseTokenAMAP",
|
|
2340
|
+
inputs: [
|
|
2341
|
+
{ name: "token", type: "address" },
|
|
2342
|
+
{ name: "funds", type: "uint256" },
|
|
2343
|
+
{ name: "minAmount", type: "uint256" }
|
|
2344
|
+
],
|
|
2345
|
+
outputs: [],
|
|
2346
|
+
stateMutability: "payable"
|
|
2347
|
+
},
|
|
2348
|
+
{
|
|
2349
|
+
type: "function",
|
|
2350
|
+
name: "saleToken",
|
|
2351
|
+
inputs: [
|
|
2352
|
+
{ name: "token", type: "address" },
|
|
2353
|
+
{ name: "amount", type: "uint256" }
|
|
2354
|
+
],
|
|
2355
|
+
outputs: [],
|
|
2356
|
+
stateMutability: "nonpayable"
|
|
2357
|
+
}
|
|
2358
|
+
];
|
|
2359
|
+
var FOUR_MEME_V2_ABI = [
|
|
2360
|
+
{
|
|
2361
|
+
type: "function",
|
|
2362
|
+
name: "buyTokenAMAP",
|
|
2363
|
+
inputs: [
|
|
2364
|
+
{ name: "token", type: "address" },
|
|
2365
|
+
{ name: "funds", type: "uint256" },
|
|
2366
|
+
{ name: "minAmount", type: "uint256" }
|
|
2367
|
+
],
|
|
2368
|
+
outputs: [],
|
|
2369
|
+
stateMutability: "payable"
|
|
2370
|
+
},
|
|
2371
|
+
{
|
|
2372
|
+
type: "function",
|
|
2373
|
+
name: "sellToken",
|
|
2374
|
+
inputs: [
|
|
2375
|
+
{ name: "token", type: "address" },
|
|
2376
|
+
{ name: "amount", type: "uint256" }
|
|
2377
|
+
],
|
|
2378
|
+
outputs: [],
|
|
2379
|
+
stateMutability: "nonpayable"
|
|
2380
|
+
}
|
|
2381
|
+
];
|
|
2382
|
+
var fourInfoCmd = new import_commander.Command("four-info").description("Query Four.meme bonding curve token info (price, progress, DEX status)").requiredOption("--token <address>", "Token contract address on Four.meme").option("-r, --rpc <url>", "BSC RPC URL", DEFAULT_RPC);
|
|
2383
|
+
fourInfoCmd.action(async (opts) => {
|
|
2384
|
+
try {
|
|
2385
|
+
const rpcUrl = opts.rpc || DEFAULT_RPC;
|
|
2386
|
+
const publicClient = (0, import_viem2.createPublicClient)({ chain: import_chains2.bsc, transport: (0, import_viem2.http)(rpcUrl) });
|
|
2387
|
+
const tokenAddr = opts.token;
|
|
2388
|
+
const info = await publicClient.readContract({
|
|
2389
|
+
address: FOUR_MEME_HELPER_V3,
|
|
2390
|
+
abi: FOUR_MEME_HELPER_ABI,
|
|
2391
|
+
functionName: "getTokenInfo",
|
|
2392
|
+
args: [tokenAddr]
|
|
2393
|
+
});
|
|
2394
|
+
const [
|
|
2395
|
+
version,
|
|
2396
|
+
tokenManager,
|
|
2397
|
+
quote,
|
|
2398
|
+
lastPrice,
|
|
2399
|
+
tradingFeeRate,
|
|
2400
|
+
minTradingFee,
|
|
2401
|
+
launchTime,
|
|
2402
|
+
offers,
|
|
2403
|
+
maxOffers,
|
|
2404
|
+
funds,
|
|
2405
|
+
maxFunds,
|
|
2406
|
+
liquidityAdded
|
|
2407
|
+
] = info;
|
|
2408
|
+
const progressPct = maxFunds > 0n ? Number(funds * 10000n / maxFunds) / 100 : 0;
|
|
2409
|
+
const offersPct = maxOffers > 0n ? Number((maxOffers - offers) * 10000n / maxOffers) / 100 : 0;
|
|
2410
|
+
output({
|
|
2411
|
+
status: "success",
|
|
2412
|
+
token: tokenAddr,
|
|
2413
|
+
version: Number(version),
|
|
2414
|
+
tokenManager,
|
|
2415
|
+
quoteToken: quote === "0x0000000000000000000000000000000000000000" ? "BNB" : quote,
|
|
2416
|
+
lastPrice: lastPrice.toString(),
|
|
2417
|
+
lastPriceHuman: (Number(lastPrice) / 1e18).toExponential(4),
|
|
2418
|
+
tradingFeeRate: `${Number(tradingFeeRate) / 100}%`,
|
|
2419
|
+
minTradingFee: minTradingFee.toString(),
|
|
2420
|
+
launchTime: new Date(Number(launchTime) * 1e3).toISOString(),
|
|
2421
|
+
offers: offers.toString(),
|
|
2422
|
+
maxOffers: maxOffers.toString(),
|
|
2423
|
+
tokensSoldPct: `${offersPct.toFixed(2)}%`,
|
|
2424
|
+
fundsRaised: funds.toString(),
|
|
2425
|
+
fundsRaisedBNB: (Number(funds) / 1e18).toFixed(4),
|
|
2426
|
+
maxFunds: maxFunds.toString(),
|
|
2427
|
+
maxFundsBNB: (Number(maxFunds) / 1e18).toFixed(4),
|
|
2428
|
+
bondingCurveProgress: `${progressPct.toFixed(2)}%`,
|
|
2429
|
+
liquidityAdded,
|
|
2430
|
+
tradingPhase: liquidityAdded ? "DEX (PancakeSwap)" : "Internal (Bonding Curve)"
|
|
2431
|
+
});
|
|
2432
|
+
} catch (error) {
|
|
2433
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
2434
|
+
output({ status: "error", message });
|
|
2435
|
+
process.exit(1);
|
|
2436
|
+
}
|
|
2437
|
+
});
|
|
2438
|
+
var fourBuyCmd = new import_commander.Command("four-buy").description("Buy tokens on Four.meme internal bonding curve using BNB").requiredOption("--token <address>", "Token contract address").requiredOption("-a, --amount <bnb>", "BNB amount to spend (human-readable, e.g. 0.01)").option("-s, --slippage <percent>", "Slippage tolerance in percent (default: 10)", "10");
|
|
2439
|
+
addSharedOptions(fourBuyCmd);
|
|
2440
|
+
fourBuyCmd.action(async (opts) => {
|
|
2441
|
+
try {
|
|
2442
|
+
const client = createClient(opts);
|
|
2443
|
+
const tokenId = BigInt(opts.tokenId);
|
|
2444
|
+
await checkAccess(opts, tokenId);
|
|
2445
|
+
const rpcUrl = opts.rpc || DEFAULT_RPC;
|
|
2446
|
+
const publicClient = (0, import_viem2.createPublicClient)({ chain: import_chains2.bsc, transport: (0, import_viem2.http)(rpcUrl) });
|
|
2447
|
+
const vault = await client.getVault(tokenId);
|
|
2448
|
+
const tokenAddr = opts.token;
|
|
2449
|
+
const slippage = Number(opts.slippage);
|
|
2450
|
+
const bnbAmount = parseAmount(opts.amount, 18);
|
|
2451
|
+
const info = await publicClient.readContract({
|
|
2452
|
+
address: FOUR_MEME_HELPER_V3,
|
|
2453
|
+
abi: FOUR_MEME_HELPER_ABI,
|
|
2454
|
+
functionName: "getTokenInfo",
|
|
2455
|
+
args: [tokenAddr]
|
|
2456
|
+
});
|
|
2457
|
+
const [version, tokenManager, quote, , , , , , , , , liquidityAdded] = info;
|
|
2458
|
+
if (liquidityAdded) {
|
|
2459
|
+
output({ status: "error", message: "Token has already migrated to DEX. Use the 'swap' command instead of 'four-buy'." });
|
|
2460
|
+
process.exit(1);
|
|
2461
|
+
}
|
|
2462
|
+
const isQuoteBNB = quote === "0x0000000000000000000000000000000000000000";
|
|
2463
|
+
if (!isQuoteBNB) {
|
|
2464
|
+
output({ status: "error", message: `Token uses BEP20 quote (${quote}), not BNB. BEP20 quote pairs are not yet supported in this tool.` });
|
|
2465
|
+
process.exit(1);
|
|
2466
|
+
}
|
|
2467
|
+
const tryBuyResult = await publicClient.readContract({
|
|
2468
|
+
address: FOUR_MEME_HELPER_V3,
|
|
2469
|
+
abi: FOUR_MEME_HELPER_ABI,
|
|
2470
|
+
functionName: "tryBuy",
|
|
2471
|
+
args: [tokenAddr, 0n, bnbAmount]
|
|
2472
|
+
});
|
|
2473
|
+
const [, , estimatedAmount, estimatedCost, estimatedFee, amountMsgValue] = tryBuyResult;
|
|
2474
|
+
const minAmount = estimatedAmount * BigInt(100 - slippage) / 100n;
|
|
2475
|
+
const alignedMinAmount = minAmount / 1000000000n * 1000000000n;
|
|
2476
|
+
output({
|
|
2477
|
+
status: "info",
|
|
2478
|
+
message: `Four.meme Buy: ~${(Number(estimatedAmount) / 1e18).toFixed(4)} tokens for ${opts.amount} BNB | fee: ${(Number(estimatedFee) / 1e18).toFixed(6)} BNB | minOut: ${(Number(alignedMinAmount) / 1e18).toFixed(4)} (${slippage}% slippage)`
|
|
2479
|
+
});
|
|
2480
|
+
let data;
|
|
2481
|
+
if (Number(version) === 1) {
|
|
2482
|
+
data = (0, import_viem2.encodeFunctionData)({
|
|
2483
|
+
abi: FOUR_MEME_V1_ABI,
|
|
2484
|
+
functionName: "purchaseTokenAMAP",
|
|
2485
|
+
args: [tokenAddr, bnbAmount, alignedMinAmount]
|
|
2486
|
+
});
|
|
2487
|
+
} else {
|
|
2488
|
+
data = (0, import_viem2.encodeFunctionData)({
|
|
2489
|
+
abi: FOUR_MEME_V2_ABI,
|
|
2490
|
+
functionName: "buyTokenAMAP",
|
|
2491
|
+
args: [tokenAddr, bnbAmount, alignedMinAmount]
|
|
2492
|
+
});
|
|
2493
|
+
}
|
|
2494
|
+
const action = {
|
|
2495
|
+
target: tokenManager,
|
|
2496
|
+
value: amountMsgValue,
|
|
2497
|
+
data
|
|
2498
|
+
};
|
|
2499
|
+
const simResult = await client.validate(tokenId, action);
|
|
2500
|
+
if (!simResult.ok) {
|
|
2501
|
+
output({ status: "rejected", reason: simResult.reason });
|
|
2502
|
+
process.exit(0);
|
|
2503
|
+
}
|
|
2504
|
+
const result = await client.execute(tokenId, action, true);
|
|
2505
|
+
output({
|
|
2506
|
+
status: "success",
|
|
2507
|
+
hash: result.hash,
|
|
2508
|
+
protocol: "four.meme",
|
|
2509
|
+
action: "buy",
|
|
2510
|
+
bnbSpent: opts.amount,
|
|
2511
|
+
estimatedTokens: (Number(estimatedAmount) / 1e18).toFixed(4)
|
|
2512
|
+
});
|
|
2513
|
+
} catch (error) {
|
|
2514
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
2515
|
+
output({ status: "error", message });
|
|
2516
|
+
process.exit(1);
|
|
2517
|
+
}
|
|
2518
|
+
});
|
|
2519
|
+
var fourSellCmd = new import_commander.Command("four-sell").description("Sell tokens on Four.meme internal bonding curve").requiredOption("--token <address>", "Token contract address").requiredOption("-a, --amount <number>", "Amount of tokens to sell (human-readable, e.g. 1000)").option("-s, --slippage <percent>", "Slippage tolerance in percent (default: 10)", "10");
|
|
2520
|
+
addSharedOptions(fourSellCmd);
|
|
2521
|
+
fourSellCmd.action(async (opts) => {
|
|
2522
|
+
try {
|
|
2523
|
+
const client = createClient(opts);
|
|
2524
|
+
const tokenId = BigInt(opts.tokenId);
|
|
2525
|
+
await checkAccess(opts, tokenId);
|
|
2526
|
+
const rpcUrl = opts.rpc || DEFAULT_RPC;
|
|
2527
|
+
const publicClient = (0, import_viem2.createPublicClient)({ chain: import_chains2.bsc, transport: (0, import_viem2.http)(rpcUrl) });
|
|
2528
|
+
const tokenAddr = opts.token;
|
|
2529
|
+
const sellAmount = parseAmount(opts.amount, 18);
|
|
2530
|
+
const alignedAmount = sellAmount / 1000000000n * 1000000000n;
|
|
2531
|
+
const info = await publicClient.readContract({
|
|
2532
|
+
address: FOUR_MEME_HELPER_V3,
|
|
2533
|
+
abi: FOUR_MEME_HELPER_ABI,
|
|
2534
|
+
functionName: "getTokenInfo",
|
|
2535
|
+
args: [tokenAddr]
|
|
2536
|
+
});
|
|
2537
|
+
const [version, tokenManager, , , , , , , , , , liquidityAdded] = info;
|
|
2538
|
+
if (liquidityAdded) {
|
|
2539
|
+
output({ status: "error", message: "Token has already migrated to DEX. Use the 'swap' command instead of 'four-sell'." });
|
|
2540
|
+
process.exit(1);
|
|
2541
|
+
}
|
|
2542
|
+
const trySellResult = await publicClient.readContract({
|
|
2543
|
+
address: FOUR_MEME_HELPER_V3,
|
|
2544
|
+
abi: FOUR_MEME_HELPER_ABI,
|
|
2545
|
+
functionName: "trySell",
|
|
2546
|
+
args: [tokenAddr, alignedAmount]
|
|
2547
|
+
});
|
|
2548
|
+
const [, , estimatedFunds, estimatedFee] = trySellResult;
|
|
2549
|
+
output({
|
|
2550
|
+
status: "info",
|
|
2551
|
+
message: `Four.meme Sell: ${opts.amount} tokens \u2192 ~${(Number(estimatedFunds) / 1e18).toFixed(6)} BNB | fee: ${(Number(estimatedFee) / 1e18).toFixed(6)} BNB`
|
|
2552
|
+
});
|
|
2553
|
+
const actions = [];
|
|
2554
|
+
const approveData = (0, import_viem2.encodeFunctionData)({
|
|
2555
|
+
abi: ERC20_ABI,
|
|
2556
|
+
functionName: "approve",
|
|
2557
|
+
args: [tokenManager, alignedAmount]
|
|
2558
|
+
});
|
|
2559
|
+
actions.push({ target: tokenAddr, value: 0n, data: approveData });
|
|
2560
|
+
let sellData;
|
|
2561
|
+
if (Number(version) === 1) {
|
|
2562
|
+
sellData = (0, import_viem2.encodeFunctionData)({
|
|
2563
|
+
abi: FOUR_MEME_V1_ABI,
|
|
2564
|
+
functionName: "saleToken",
|
|
2565
|
+
args: [tokenAddr, alignedAmount]
|
|
2566
|
+
});
|
|
2567
|
+
} else {
|
|
2568
|
+
sellData = (0, import_viem2.encodeFunctionData)({
|
|
2569
|
+
abi: FOUR_MEME_V2_ABI,
|
|
2570
|
+
functionName: "sellToken",
|
|
2571
|
+
args: [tokenAddr, alignedAmount]
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2574
|
+
actions.push({ target: tokenManager, value: 0n, data: sellData });
|
|
2575
|
+
for (const action of actions) {
|
|
2576
|
+
const simResult = await client.validate(tokenId, action);
|
|
2577
|
+
if (!simResult.ok) {
|
|
2578
|
+
output({ status: "rejected", reason: simResult.reason });
|
|
2579
|
+
process.exit(0);
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
const result = await client.executeBatch(tokenId, actions, true);
|
|
2583
|
+
output({
|
|
2584
|
+
status: "success",
|
|
2585
|
+
hash: result.hash,
|
|
2586
|
+
protocol: "four.meme",
|
|
2587
|
+
action: "sell",
|
|
2588
|
+
tokensSold: opts.amount,
|
|
2589
|
+
estimatedBNB: (Number(estimatedFunds) / 1e18).toFixed(6)
|
|
2590
|
+
});
|
|
2591
|
+
} catch (error) {
|
|
2592
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
2593
|
+
output({ status: "error", message });
|
|
2594
|
+
process.exit(1);
|
|
2595
|
+
}
|
|
2596
|
+
});
|
|
2278
2597
|
program.addCommand(swapCmd);
|
|
2279
2598
|
program.addCommand(rawCmd);
|
|
2280
2599
|
program.addCommand(tokensCmd);
|
|
@@ -2297,4 +2616,7 @@ program.addCommand(lendCmd);
|
|
|
2297
2616
|
program.addCommand(redeemCmd);
|
|
2298
2617
|
program.addCommand(lendingInfoCmd);
|
|
2299
2618
|
program.addCommand(myAgentsCmd);
|
|
2619
|
+
program.addCommand(fourInfoCmd);
|
|
2620
|
+
program.addCommand(fourBuyCmd);
|
|
2621
|
+
program.addCommand(fourSellCmd);
|
|
2300
2622
|
program.parse(process.argv);
|