shll-skills 5.4.1 → 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 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.1
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
@@ -1036,6 +1036,7 @@ rawCmd.action(async (opts) => {
1036
1036
  try {
1037
1037
  const client = createClient(opts);
1038
1038
  const tokenId = BigInt(opts.tokenId);
1039
+ await checkAccess(opts, tokenId);
1039
1040
  let actions;
1040
1041
  if (opts.batch) {
1041
1042
  if (!opts.actions) {
@@ -2274,6 +2275,325 @@ myAgentsCmd.action(async (opts) => {
2274
2275
  process.exit(1);
2275
2276
  }
2276
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
+ });
2277
2597
  program.addCommand(swapCmd);
2278
2598
  program.addCommand(rawCmd);
2279
2599
  program.addCommand(tokensCmd);
@@ -2296,4 +2616,7 @@ program.addCommand(lendCmd);
2296
2616
  program.addCommand(redeemCmd);
2297
2617
  program.addCommand(lendingInfoCmd);
2298
2618
  program.addCommand(myAgentsCmd);
2619
+ program.addCommand(fourInfoCmd);
2620
+ program.addCommand(fourBuyCmd);
2621
+ program.addCommand(fourSellCmd);
2299
2622
  program.parse(process.argv);