moltlaunch 0.1.5 → 0.2.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
@@ -41,7 +41,8 @@ Returns:
41
41
  | `moltlaunch wallet` | Show wallet address and balance |
42
42
  | `moltlaunch wallet --show-key` | Show wallet with private key |
43
43
  | `moltlaunch status` | List all launched tokens |
44
- | `moltlaunch claim` | Claim accumulated trading fees |
44
+ | `moltlaunch fees` | Check claimable fee balance (no gas needed) |
45
+ | `moltlaunch claim` | Withdraw accumulated trading fees |
45
46
 
46
47
  All commands support `--json` for structured output.
47
48
 
@@ -104,6 +105,15 @@ Trade executes on Uniswap V4 (Base)
104
105
 
105
106
  The swap fee is dynamic — 1% baseline, scaling with volume up to 50%, decaying over a 1-hour window. Tokens trade heaviest at launch, which is when creator fees are highest.
106
107
 
108
+ ### Checking fees
109
+
110
+ Check how much you've earned without spending gas:
111
+
112
+ ```bash
113
+ moltlaunch fees # human-readable
114
+ moltlaunch fees --json # structured output with canClaim boolean
115
+ ```
116
+
107
117
  ### Claiming fees
108
118
 
109
119
  Fees accumulate in escrow on the Flaunch PositionManager. Withdraw anytime:
@@ -113,7 +123,7 @@ moltlaunch claim # withdraw to your wallet
113
123
  moltlaunch claim --json # structured output
114
124
  ```
115
125
 
116
- Requires ETH in your wallet for gas (claiming is an on-chain transaction).
126
+ Requires ETH in your wallet for gas (claiming is an on-chain transaction). Use `fees` first to check if there's anything to claim.
117
127
 
118
128
  ## Exit Codes
119
129
 
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
+ import { createRequire } from "module";
4
5
  import { Command } from "commander";
5
6
 
6
7
  // src/commands/launch.ts
@@ -393,7 +394,8 @@ async function wallet(opts) {
393
394
  }
394
395
  const output = {
395
396
  address: data.address,
396
- balance: `${balance} ETH (Base)`,
397
+ balance: json ? balance : `${balance} ETH (Base)`,
398
+ network: json ? "Base" : void 0,
397
399
  createdAt: data.createdAt
398
400
  };
399
401
  if (showKey) {
@@ -487,9 +489,50 @@ Claimable: ${claimableEth} ETH`);
487
489
  }
488
490
  }
489
491
 
492
+ // src/commands/fees.ts
493
+ import { ethers as ethers3 } from "ethers";
494
+ var POSITION_MANAGER_ABI2 = [
495
+ "function balances(address) external view returns (uint256)"
496
+ ];
497
+ async function fees(opts) {
498
+ const { testnet, json } = opts;
499
+ const network = testnet ? "testnet" : "mainnet";
500
+ try {
501
+ const walletData = await loadWallet();
502
+ if (!walletData) {
503
+ throw new NoWalletError();
504
+ }
505
+ const chain = testnet ? CHAIN.testnet : CHAIN.mainnet;
506
+ const provider = new ethers3.JsonRpcProvider(chain.rpcUrl);
507
+ const pm = new ethers3.Contract(POSITION_MANAGER_ADDRESS, POSITION_MANAGER_ABI2, provider);
508
+ const claimable = await pm.balances(walletData.address);
509
+ const claimableEth = ethers3.formatEther(claimable);
510
+ const walletBalance = await getWalletBalance(walletData.address, network);
511
+ const hasGas = parseFloat(walletBalance) > 0;
512
+ printSuccess("Fee balance", {
513
+ claimable: `${claimableEth} ETH`,
514
+ wallet: walletData.address,
515
+ walletBalance: `${walletBalance} ETH`,
516
+ hasGas,
517
+ network: chain.name,
518
+ canClaim: hasGas && claimable > 0n
519
+ }, json);
520
+ } catch (error) {
521
+ if (error instanceof MoltlaunchError) {
522
+ printError(error.message, json, error.exitCode);
523
+ process.exit(error.exitCode);
524
+ }
525
+ const message = error instanceof Error ? error.message : String(error);
526
+ printError(message, json, EXIT_CODES.GENERAL);
527
+ process.exit(EXIT_CODES.GENERAL);
528
+ }
529
+ }
530
+
490
531
  // src/index.ts
532
+ var require2 = createRequire(import.meta.url);
533
+ var { version } = require2("../package.json");
491
534
  var program = new Command();
492
- program.name("moltlaunch").description("CLI for AI agents to launch tokens on Base via Flaunch").version("0.1.0");
535
+ program.name("moltlaunch").description("CLI for AI agents to launch tokens on Base via Flaunch").version(version);
493
536
  program.command("launch", { isDefault: true }).description("Launch a new token on Base").requiredOption("--name <name>", "Token name").requiredOption("--symbol <symbol>", "Token symbol").requiredOption("--description <desc>", "Token description").requiredOption("--image <path>", "Path to token image (max 5MB)").option("--testnet", "Use Base Sepolia testnet", false).option("--json", "Output as JSON (for agents)", false).action((opts) => {
494
537
  launch({
495
538
  name: opts.name,
@@ -506,6 +549,9 @@ program.command("wallet").description("Show wallet address and balance").option(
506
549
  program.command("status").description("List launched tokens").option("--json", "Output as JSON", false).action((opts) => {
507
550
  status({ json: opts.json });
508
551
  });
552
+ program.command("fees").description("Check claimable fee balance (read-only, no gas needed)").option("--testnet", "Use Base Sepolia testnet", false).option("--json", "Output as JSON", false).action((opts) => {
553
+ fees({ testnet: opts.testnet, json: opts.json });
554
+ });
509
555
  program.command("claim").description("Withdraw accumulated fees from PositionManager escrow").option("--testnet", "Use Base Sepolia testnet", false).option("--json", "Output as JSON", false).action((opts) => {
510
556
  claim({ testnet: opts.testnet, json: opts.json });
511
557
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/launch.ts","../src/lib/wallet.ts","../src/lib/config.ts","../src/lib/flaunch-api.ts","../src/lib/errors.ts","../src/lib/output.ts","../src/commands/wallet.ts","../src/commands/status.ts","../src/commands/claim.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { launch } from \"./commands/launch.js\";\nimport { wallet } from \"./commands/wallet.js\";\nimport { status } from \"./commands/status.js\";\nimport { claim } from \"./commands/claim.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"moltlaunch\")\n .description(\"CLI for AI agents to launch tokens on Base via Flaunch\")\n .version(\"0.1.0\");\n\n// Default command: launch a token\nprogram\n .command(\"launch\", { isDefault: true })\n .description(\"Launch a new token on Base\")\n .requiredOption(\"--name <name>\", \"Token name\")\n .requiredOption(\"--symbol <symbol>\", \"Token symbol\")\n .requiredOption(\"--description <desc>\", \"Token description\")\n .requiredOption(\"--image <path>\", \"Path to token image (max 5MB)\")\n .option(\"--testnet\", \"Use Base Sepolia testnet\", false)\n .option(\"--json\", \"Output as JSON (for agents)\", false)\n .action((opts) => {\n launch({\n name: opts.name,\n symbol: opts.symbol,\n description: opts.description,\n imagePath: opts.image,\n testnet: opts.testnet,\n json: opts.json,\n });\n });\n\nprogram\n .command(\"wallet\")\n .description(\"Show wallet address and balance\")\n .option(\"--show-key\", \"Show private key\", false)\n .option(\"--json\", \"Output as JSON\", false)\n .action((opts) => {\n wallet({ showKey: opts.showKey, json: opts.json });\n });\n\nprogram\n .command(\"status\")\n .description(\"List launched tokens\")\n .option(\"--json\", \"Output as JSON\", false)\n .action((opts) => {\n status({ json: opts.json });\n });\n\nprogram\n .command(\"claim\")\n .description(\"Withdraw accumulated fees from PositionManager escrow\")\n .option(\"--testnet\", \"Use Base Sepolia testnet\", false)\n .option(\"--json\", \"Output as JSON\", false)\n .action((opts) => {\n claim({ testnet: opts.testnet, json: opts.json });\n });\n\nprogram.parse();\n","import { resolve } from \"node:path\";\nimport { access } from \"node:fs/promises\";\nimport { loadOrCreateWallet, saveLaunchRecord } from \"../lib/wallet.js\";\nimport { uploadImage, launchMemecoin, pollLaunchStatus } from \"../lib/flaunch-api.js\";\nimport { printSuccess, printError } from \"../lib/output.js\";\nimport { CHAIN, REVENUE_MANAGER_ADDRESS } from \"../lib/config.js\";\nimport { MoltlaunchError, EXIT_CODES } from \"../lib/errors.js\";\nimport type { LaunchParams, Network } from \"../types.js\";\n\nexport async function launch(opts: LaunchParams): Promise<void> {\n const { name, symbol, description, imagePath, testnet, json } = opts;\n const network: Network = testnet ? \"testnet\" : \"mainnet\";\n const chain = testnet ? CHAIN.testnet : CHAIN.mainnet;\n\n try {\n // Validate image exists\n const resolvedImage = resolve(imagePath);\n try {\n await access(resolvedImage);\n } catch {\n printError(`Image not found: ${resolvedImage}`, json, EXIT_CODES.UPLOAD_FAIL);\n process.exit(EXIT_CODES.UPLOAD_FAIL);\n }\n\n // Step 1: Load or create wallet\n const { wallet, isNew } = await loadOrCreateWallet();\n\n if (!json) {\n if (isNew) {\n console.log(`\\nWallet created: ${wallet.address}`);\n console.log(`Private key: ${wallet.privateKey}`);\n console.log(\"(Save this key — it will not be shown again)\\n\");\n } else {\n console.log(`\\nUsing wallet: ${wallet.address}`);\n }\n }\n\n // Step 2: Upload image to IPFS\n if (!json) process.stdout.write(\"Uploading image...\");\n const imageIpfs = await uploadImage(resolvedImage);\n if (!json) console.log(` ${imageIpfs.slice(0, 16)}...`);\n\n // Step 3: Launch via Flaunch Web2 API (gasless — Flaunch handles on-chain tx)\n if (!json) process.stdout.write(\"Submitting launch...\");\n const jobId = await launchMemecoin({\n name,\n symbol,\n description,\n imageIpfs,\n creatorAddress: wallet.address,\n revenueManagerAddress: REVENUE_MANAGER_ADDRESS,\n network,\n });\n if (!json) console.log(` queued (job ${jobId})`);\n\n // Step 4: Poll for completion\n if (!json) process.stdout.write(\"Deploying on-chain\");\n const result = await pollLaunchStatus(jobId, (state, position) => {\n if (!json) {\n if (position > 0) {\n process.stdout.write(` [queue: ${position}]`);\n } else {\n process.stdout.write(\".\");\n }\n }\n });\n if (!json) console.log(\" done\");\n\n const tokenAddress = result.collectionToken!.address;\n const flaunchUrl = `${chain.flaunchUrl}/coin/${tokenAddress}`;\n\n // Step 5: Save launch record\n await saveLaunchRecord({\n name,\n symbol,\n tokenAddress,\n transactionHash: result.transactionHash!,\n network,\n walletAddress: wallet.address,\n launchedAt: new Date().toISOString(),\n flaunchUrl,\n });\n\n // Output result\n const outputData: Record<string, unknown> = {\n tokenAddress,\n transactionHash: result.transactionHash,\n name,\n symbol,\n network: chain.name,\n explorer: `${chain.explorer}/token/${tokenAddress}`,\n flaunch: flaunchUrl,\n wallet: wallet.address,\n };\n\n if (isNew) {\n outputData.privateKey = wallet.privateKey;\n outputData.walletNote = \"Save this private key — it will not be shown again\";\n }\n\n printSuccess(\"Token launched successfully!\", outputData, json);\n } catch (error) {\n if (error instanceof MoltlaunchError) {\n printError(error.message, json, error.exitCode);\n process.exit(error.exitCode);\n }\n const message = error instanceof Error ? error.message : String(error);\n printError(message, json, EXIT_CODES.GENERAL);\n process.exit(EXIT_CODES.GENERAL);\n }\n}\n","import { ethers } from \"ethers\";\nimport { readFile, writeFile, mkdir, chmod, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { WALLET_DIR, WALLET_FILE, LAUNCHES_FILE, CHAIN } from \"./config.js\";\nimport type { WalletData, LaunchRecord, Network } from \"../types.js\";\n\nfunction getWalletDir(): string {\n return join(homedir(), WALLET_DIR);\n}\n\nfunction getWalletPath(): string {\n return join(getWalletDir(), WALLET_FILE);\n}\n\nfunction getLaunchesPath(): string {\n return join(getWalletDir(), LAUNCHES_FILE);\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function walletExists(): Promise<boolean> {\n return fileExists(getWalletPath());\n}\n\nexport async function loadWallet(): Promise<WalletData | null> {\n const path = getWalletPath();\n if (!(await fileExists(path))) return null;\n\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw) as WalletData;\n}\n\nexport async function createWallet(): Promise<WalletData> {\n const wallet = ethers.Wallet.createRandom();\n const data: WalletData = {\n address: wallet.address,\n privateKey: wallet.privateKey,\n createdAt: new Date().toISOString(),\n };\n\n const dir = getWalletDir();\n await mkdir(dir, { recursive: true });\n\n const path = getWalletPath();\n await writeFile(path, JSON.stringify(data, null, 2), { mode: 0o600 });\n await chmod(path, 0o600);\n\n return data;\n}\n\nexport async function loadOrCreateWallet(): Promise<{ wallet: WalletData; isNew: boolean }> {\n const existing = await loadWallet();\n if (existing) return { wallet: existing, isNew: false };\n\n const wallet = await createWallet();\n return { wallet, isNew: true };\n}\n\nexport async function getWalletBalance(address: string, network: Network): Promise<string> {\n const chain = network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n const provider = new ethers.JsonRpcProvider(chain.rpcUrl);\n const balance = await provider.getBalance(address);\n return ethers.formatEther(balance);\n}\n\nexport async function getSigner(privateKey: string, network: Network): Promise<ethers.Wallet> {\n const chain = network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n const provider = new ethers.JsonRpcProvider(chain.rpcUrl);\n return new ethers.Wallet(privateKey, provider);\n}\n\nexport async function saveLaunchRecord(record: LaunchRecord): Promise<void> {\n const path = getLaunchesPath();\n let records: LaunchRecord[] = [];\n\n if (await fileExists(path)) {\n const raw = await readFile(path, \"utf-8\");\n records = JSON.parse(raw) as LaunchRecord[];\n }\n\n records.push(record);\n\n const dir = getWalletDir();\n await mkdir(dir, { recursive: true });\n await writeFile(path, JSON.stringify(records, null, 2), { mode: 0o600 });\n}\n\nexport async function loadLaunchRecords(): Promise<LaunchRecord[]> {\n const path = getLaunchesPath();\n if (!(await fileExists(path))) return [];\n\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw) as LaunchRecord[];\n}\n","export const REVENUE_MANAGER_ADDRESS = \"0x3Bc08524d9DaaDEC9d1Af87818d809611F0fD669\";\n\n// Flaunch PositionManager — fees accumulate here in escrow\nexport const POSITION_MANAGER_ADDRESS = \"0x51Bba15255406Cfe7099a42183302640ba7dAFDC\";\n\nexport const FLAUNCH_API_BASE = \"https://web2-api.flaunch.gg\";\n\nexport const CHAIN = {\n mainnet: {\n id: 8453,\n name: \"Base\",\n network: \"base\",\n rpcUrl: \"https://mainnet.base.org\",\n explorer: \"https://basescan.org\",\n flaunchUrl: \"https://flaunch.gg/base\",\n },\n testnet: {\n id: 84532,\n name: \"Base Sepolia\",\n network: \"base-sepolia\",\n rpcUrl: \"https://sepolia.base.org\",\n explorer: \"https://sepolia.basescan.org\",\n flaunchUrl: \"https://flaunch.gg/base-sepolia\",\n },\n} as const;\n\nexport const WALLET_DIR = \".moltlaunch\";\nexport const WALLET_FILE = \"wallet.json\";\nexport const LAUNCHES_FILE = \"launches.json\";\n\nexport const MAX_IMAGE_SIZE_BYTES = 5 * 1024 * 1024; // 5MB\nexport const POLL_INTERVAL_MS = 2000;\nexport const POLL_TIMEOUT_MS = 120_000;\n","import { readFile, stat } from \"node:fs/promises\";\nimport {\n FLAUNCH_API_BASE,\n CHAIN,\n MAX_IMAGE_SIZE_BYTES,\n POLL_INTERVAL_MS,\n POLL_TIMEOUT_MS,\n} from \"./config.js\";\nimport { UploadError, LaunchError, TimeoutError } from \"./errors.js\";\nimport type {\n Network,\n FlaunchUploadResponse,\n FlaunchLaunchResponse,\n FlaunchStatusResponse,\n} from \"../types.js\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function fetchWithRetry(\n url: string,\n options: RequestInit,\n retries = 3,\n): Promise<Response> {\n for (let attempt = 0; attempt < retries; attempt++) {\n const response = await fetch(url, options);\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : 2000 * (attempt + 1);\n await sleep(waitMs);\n continue;\n }\n\n return response;\n }\n\n throw new Error(\"Max retries exceeded (429 rate limit)\");\n}\n\n/**\n * Upload image to IPFS via Flaunch Web2 API.\n * Reads file as base64 data URL, returns IPFS hash.\n */\nexport async function uploadImage(imagePath: string): Promise<string> {\n const fileStat = await stat(imagePath);\n if (fileStat.size > MAX_IMAGE_SIZE_BYTES) {\n throw new UploadError(`Image exceeds 5MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)}MB)`);\n }\n\n const imageBuffer = await readFile(imagePath);\n const base64 = imageBuffer.toString(\"base64\");\n\n const ext = imagePath.split(\".\").pop()?.toLowerCase();\n const mimeMap: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n };\n const mime = mimeMap[ext ?? \"\"] ?? \"image/png\";\n const dataUrl = `data:${mime};base64,${base64}`;\n\n const response = await fetchWithRetry(`${FLAUNCH_API_BASE}/api/v1/upload-image`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ base64Image: dataUrl }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new UploadError(`${response.status} — ${text}`);\n }\n\n const data = (await response.json()) as FlaunchUploadResponse;\n return data.ipfsHash;\n}\n\n/**\n * Launch a memecoin via Flaunch Web2 API.\n * This is gasless — Flaunch handles the on-chain transaction server-side.\n */\nexport async function launchMemecoin(params: {\n name: string;\n symbol: string;\n description: string;\n imageIpfs: string;\n creatorAddress: string;\n revenueManagerAddress?: string;\n network: Network;\n}): Promise<string> {\n const chain = params.network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n\n const body = {\n name: params.name,\n symbol: params.symbol,\n description: params.description,\n imageIpfs: params.imageIpfs,\n creatorAddress: params.creatorAddress,\n revenueManagerAddress: params.revenueManagerAddress,\n };\n\n const response = await fetchWithRetry(\n `${FLAUNCH_API_BASE}/api/v1/${chain.network}/launch-memecoin`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new LaunchError(`${response.status} — ${text}`);\n }\n\n const data = (await response.json()) as FlaunchLaunchResponse;\n return data.jobId;\n}\n\n/**\n * Poll launch status until completed or failed.\n */\nexport async function pollLaunchStatus(\n jobId: string,\n onPoll?: (state: string, position: number) => void,\n): Promise<FlaunchStatusResponse> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n const response = await fetch(`${FLAUNCH_API_BASE}/api/v1/launch-status/${jobId}`);\n\n if (!response.ok) {\n const text = await response.text();\n throw new LaunchError(`Status check failed: ${response.status} — ${text}`);\n }\n\n const data = (await response.json()) as FlaunchStatusResponse;\n onPoll?.(data.state, data.queuePosition);\n\n if (data.state === \"completed\") return data;\n if (data.state === \"failed\") {\n throw new LaunchError(data.error ?? \"Launch failed with no error message\");\n }\n\n await sleep(POLL_INTERVAL_MS);\n }\n\n throw new TimeoutError();\n}\n","export const EXIT_CODES = {\n SUCCESS: 0,\n GENERAL: 1,\n NO_WALLET: 2,\n UPLOAD_FAIL: 3,\n LAUNCH_FAIL: 4,\n TIMEOUT: 5,\n NO_GAS: 6,\n} as const;\n\nexport class MoltlaunchError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number,\n ) {\n super(message);\n this.name = \"MoltlaunchError\";\n }\n}\n\nexport class NoWalletError extends MoltlaunchError {\n constructor() {\n super(\"No wallet found. Run `moltlaunch` to create one.\", EXIT_CODES.NO_WALLET);\n }\n}\n\nexport class UploadError extends MoltlaunchError {\n constructor(detail: string) {\n super(`Image upload failed: ${detail}`, EXIT_CODES.UPLOAD_FAIL);\n }\n}\n\nexport class LaunchError extends MoltlaunchError {\n constructor(detail: string) {\n super(`Token launch failed: ${detail}`, EXIT_CODES.LAUNCH_FAIL);\n }\n}\n\nexport class TimeoutError extends MoltlaunchError {\n constructor() {\n super(\"Launch timed out waiting for confirmation.\", EXIT_CODES.TIMEOUT);\n }\n}\n\nexport class NoGasError extends MoltlaunchError {\n constructor(address: string) {\n super(\n `Wallet ${address} has no ETH for gas. Send Base ETH to this address and retry.`,\n EXIT_CODES.NO_GAS,\n );\n }\n}\n","export function formatOutput(data: Record<string, unknown>, json: boolean): string {\n if (json) {\n return JSON.stringify(data, null, 2);\n }\n\n const lines: string[] = [];\n for (const [key, value] of Object.entries(data)) {\n if (value === undefined || value === null) continue;\n const label = key.replace(/([A-Z])/g, \" $1\").replace(/^./, (s) => s.toUpperCase());\n lines.push(` ${label}: ${String(value)}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function printSuccess(message: string, data: Record<string, unknown>, json: boolean): void {\n if (json) {\n console.log(JSON.stringify({ success: true, ...data }, null, 2));\n } else {\n console.log(`\\n${message}\\n`);\n console.log(formatOutput(data, false));\n console.log();\n }\n}\n\nexport function printError(message: string, json: boolean, exitCode: number): void {\n if (json) {\n console.error(JSON.stringify({ success: false, error: message, exitCode }));\n } else {\n console.error(`\\nError: ${message}\\n`);\n }\n}\n","import { loadWallet, getWalletBalance } from \"../lib/wallet.js\";\nimport { printSuccess, printError } from \"../lib/output.js\";\nimport { EXIT_CODES } from \"../lib/errors.js\";\n\ninterface WalletOpts {\n showKey: boolean;\n json: boolean;\n}\n\nexport async function wallet(opts: WalletOpts): Promise<void> {\n const { showKey, json } = opts;\n\n const data = await loadWallet();\n if (!data) {\n printError(\"No wallet found. Run `moltlaunch` to create one.\", json, EXIT_CODES.NO_WALLET);\n process.exit(EXIT_CODES.NO_WALLET);\n }\n\n let balance = \"unknown\";\n try {\n balance = await getWalletBalance(data.address, \"mainnet\");\n } catch {\n // RPC may be unreachable\n }\n\n const output: Record<string, unknown> = {\n address: data.address,\n balance: `${balance} ETH (Base)`,\n createdAt: data.createdAt,\n };\n\n if (showKey) {\n output.privateKey = data.privateKey;\n }\n\n printSuccess(\"Wallet info\", output, json);\n}\n","import { loadLaunchRecords } from \"../lib/wallet.js\";\n\ninterface StatusOpts {\n json: boolean;\n}\n\nexport async function status(opts: StatusOpts): Promise<void> {\n const { json } = opts;\n const records = await loadLaunchRecords();\n\n if (records.length === 0) {\n if (json) {\n console.log(JSON.stringify({ success: true, launches: [] }));\n } else {\n console.log(\"\\nNo tokens launched yet. Run `moltlaunch` to launch one.\\n\");\n }\n return;\n }\n\n if (json) {\n console.log(JSON.stringify({ success: true, launches: records }, null, 2));\n return;\n }\n\n console.log(`\\nLaunched tokens (${records.length}):\\n`);\n for (const record of records) {\n console.log(` ${record.name} (${record.symbol})`);\n console.log(` Token: ${record.tokenAddress}`);\n console.log(` TX: ${record.transactionHash}`);\n console.log(` Flaunch: ${record.flaunchUrl}`);\n console.log(` Network: ${record.network}`);\n console.log(` Launched: ${record.launchedAt}`);\n console.log();\n }\n}\n","import { ethers } from \"ethers\";\nimport { loadWallet, getSigner, getWalletBalance } from \"../lib/wallet.js\";\nimport { POSITION_MANAGER_ADDRESS } from \"../lib/config.js\";\nimport { printSuccess, printError } from \"../lib/output.js\";\nimport { EXIT_CODES, NoWalletError, NoGasError, MoltlaunchError } from \"../lib/errors.js\";\nimport type { Network } from \"../types.js\";\n\n// Fees accumulate in escrow on the PositionManager, not on the Revenue Manager\nconst POSITION_MANAGER_ABI = [\n \"function balances(address) external view returns (uint256)\",\n \"function withdrawFees(address _recipient, bool _unwrap) external\",\n];\n\ninterface ClaimOpts {\n testnet: boolean;\n json: boolean;\n}\n\nexport async function claim(opts: ClaimOpts): Promise<void> {\n const { testnet, json } = opts;\n const network: Network = testnet ? \"testnet\" : \"mainnet\";\n\n try {\n const walletData = await loadWallet();\n if (!walletData) {\n throw new NoWalletError();\n }\n\n // Check gas balance\n const balance = await getWalletBalance(walletData.address, network);\n if (parseFloat(balance) === 0) {\n throw new NoGasError(walletData.address);\n }\n\n const signer = await getSigner(walletData.privateKey, network);\n const pm = new ethers.Contract(POSITION_MANAGER_ADDRESS, POSITION_MANAGER_ABI, signer);\n\n // Check claimable balance\n const claimable = await pm.balances(walletData.address);\n const claimableEth = ethers.formatEther(claimable);\n\n if (claimable === 0n) {\n printSuccess(\"No fees to claim\", {\n claimable: \"0 ETH\",\n wallet: walletData.address,\n network,\n }, json);\n return;\n }\n\n if (!json) console.log(`\\nClaimable: ${claimableEth} ETH`);\n if (!json) process.stdout.write(\"Submitting withdraw transaction...\");\n\n // withdrawFees sends to _recipient, _unwrap=true converts flETH→ETH\n const tx = await pm.withdrawFees(walletData.address, true);\n if (!json) console.log(` tx ${tx.hash}`);\n\n if (!json) process.stdout.write(\"Waiting for confirmation...\");\n const receipt = await tx.wait();\n if (!json) console.log(\" confirmed\");\n\n printSuccess(\"Fees claimed successfully!\", {\n transactionHash: receipt.hash,\n claimed: `${claimableEth} ETH`,\n wallet: walletData.address,\n network,\n }, json);\n } catch (error) {\n if (error instanceof MoltlaunchError) {\n printError(error.message, json, error.exitCode);\n process.exit(error.exitCode);\n }\n const message = error instanceof Error ? error.message : String(error);\n printError(message, json, EXIT_CODES.GENERAL);\n process.exit(EXIT_CODES.GENERAL);\n }\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;;;ACAxB,SAAS,eAAe;AACxB,SAAS,UAAAA,eAAc;;;ACDvB,SAAS,cAAc;AACvB,SAAS,UAAU,WAAW,OAAO,OAAO,cAAc;AAC1D,SAAS,YAAY;AACrB,SAAS,eAAe;;;ACHjB,IAAM,0BAA0B;AAGhC,IAAM,2BAA2B;AAEjC,IAAM,mBAAmB;AAEzB,IAAM,QAAQ;AAAA,EACnB,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AACF;AAEO,IAAM,aAAa;AACnB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AAEtB,IAAM,uBAAuB,IAAI,OAAO;AACxC,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;;;ADzB/B,SAAS,eAAuB;AAC9B,SAAO,KAAK,QAAQ,GAAG,UAAU;AACnC;AAEA,SAAS,gBAAwB;AAC/B,SAAO,KAAK,aAAa,GAAG,WAAW;AACzC;AAEA,SAAS,kBAA0B;AACjC,SAAO,KAAK,aAAa,GAAG,aAAa;AAC3C;AAEA,eAAe,WAAW,MAAgC;AACxD,MAAI;AACF,UAAM,OAAO,IAAI;AACjB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,eAAsB,aAAyC;AAC7D,QAAM,OAAO,cAAc;AAC3B,MAAI,CAAE,MAAM,WAAW,IAAI,EAAI,QAAO;AAEtC,QAAM,MAAM,MAAM,SAAS,MAAM,OAAO;AACxC,SAAO,KAAK,MAAM,GAAG;AACvB;AAEA,eAAsB,eAAoC;AACxD,QAAMC,UAAS,OAAO,OAAO,aAAa;AAC1C,QAAM,OAAmB;AAAA,IACvB,SAASA,QAAO;AAAA,IAChB,YAAYA,QAAO;AAAA,IACnB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAEA,QAAM,MAAM,aAAa;AACzB,QAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAEpC,QAAM,OAAO,cAAc;AAC3B,QAAM,UAAU,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AACpE,QAAM,MAAM,MAAM,GAAK;AAEvB,SAAO;AACT;AAEA,eAAsB,qBAAsE;AAC1F,QAAM,WAAW,MAAM,WAAW;AAClC,MAAI,SAAU,QAAO,EAAE,QAAQ,UAAU,OAAO,MAAM;AAEtD,QAAMA,UAAS,MAAM,aAAa;AAClC,SAAO,EAAE,QAAAA,SAAQ,OAAO,KAAK;AAC/B;AAEA,eAAsB,iBAAiB,SAAiB,SAAmC;AACzF,QAAM,QAAQ,YAAY,YAAY,MAAM,UAAU,MAAM;AAC5D,QAAM,WAAW,IAAI,OAAO,gBAAgB,MAAM,MAAM;AACxD,QAAM,UAAU,MAAM,SAAS,WAAW,OAAO;AACjD,SAAO,OAAO,YAAY,OAAO;AACnC;AAEA,eAAsB,UAAU,YAAoB,SAA0C;AAC5F,QAAM,QAAQ,YAAY,YAAY,MAAM,UAAU,MAAM;AAC5D,QAAM,WAAW,IAAI,OAAO,gBAAgB,MAAM,MAAM;AACxD,SAAO,IAAI,OAAO,OAAO,YAAY,QAAQ;AAC/C;AAEA,eAAsB,iBAAiB,QAAqC;AAC1E,QAAM,OAAO,gBAAgB;AAC7B,MAAI,UAA0B,CAAC;AAE/B,MAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,UAAM,MAAM,MAAM,SAAS,MAAM,OAAO;AACxC,cAAU,KAAK,MAAM,GAAG;AAAA,EAC1B;AAEA,UAAQ,KAAK,MAAM;AAEnB,QAAM,MAAM,aAAa;AACzB,QAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACpC,QAAM,UAAU,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AACzE;AAEA,eAAsB,oBAA6C;AACjE,QAAM,OAAO,gBAAgB;AAC7B,MAAI,CAAE,MAAM,WAAW,IAAI,EAAI,QAAO,CAAC;AAEvC,QAAM,MAAM,MAAM,SAAS,MAAM,OAAO;AACxC,SAAO,KAAK,MAAM,GAAG;AACvB;;;AErGA,SAAS,YAAAC,WAAU,YAAY;;;ACAxB,IAAM,aAAa;AAAA,EACxB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,SAAS;AAAA,EACT,QAAQ;AACV;AAEO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACE,SACgB,UAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,gBAAN,cAA4B,gBAAgB;AAAA,EACjD,cAAc;AACZ,UAAM,oDAAoD,WAAW,SAAS;AAAA,EAChF;AACF;AAEO,IAAM,cAAN,cAA0B,gBAAgB;AAAA,EAC/C,YAAY,QAAgB;AAC1B,UAAM,wBAAwB,MAAM,IAAI,WAAW,WAAW;AAAA,EAChE;AACF;AAEO,IAAM,cAAN,cAA0B,gBAAgB;AAAA,EAC/C,YAAY,QAAgB;AAC1B,UAAM,wBAAwB,MAAM,IAAI,WAAW,WAAW;AAAA,EAChE;AACF;AAEO,IAAM,eAAN,cAA2B,gBAAgB;AAAA,EAChD,cAAc;AACZ,UAAM,8CAA8C,WAAW,OAAO;AAAA,EACxE;AACF;AAEO,IAAM,aAAN,cAAyB,gBAAgB;AAAA,EAC9C,YAAY,SAAiB;AAC3B;AAAA,MACE,UAAU,OAAO;AAAA,MACjB,WAAW;AAAA,IACb;AAAA,EACF;AACF;;;ADnCA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,EAAE,CAAC;AACzD;AAEA,eAAe,eACb,KACA,SACA,UAAU,GACS;AACnB,WAAS,UAAU,GAAG,UAAU,SAAS,WAAW;AAClD,UAAM,WAAW,MAAM,MAAM,KAAK,OAAO;AAEzC,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AACrD,YAAM,SAAS,aAAa,SAAS,YAAY,EAAE,IAAI,MAAO,OAAQ,UAAU;AAChF,YAAM,MAAM,MAAM;AAClB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,uCAAuC;AACzD;AAMA,eAAsB,YAAY,WAAoC;AACpE,QAAM,WAAW,MAAM,KAAK,SAAS;AACrC,MAAI,SAAS,OAAO,sBAAsB;AACxC,UAAM,IAAI,YAAY,6BAA6B,SAAS,OAAO,OAAO,MAAM,QAAQ,CAAC,CAAC,KAAK;AAAA,EACjG;AAEA,QAAM,cAAc,MAAMC,UAAS,SAAS;AAC5C,QAAM,SAAS,YAAY,SAAS,QAAQ;AAE5C,QAAM,MAAM,UAAU,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AACpD,QAAM,UAAkC;AAAA,IACtC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,KAAK;AAAA,IACL,MAAM;AAAA,IACN,KAAK;AAAA,EACP;AACA,QAAM,OAAO,QAAQ,OAAO,EAAE,KAAK;AACnC,QAAM,UAAU,QAAQ,IAAI,WAAW,MAAM;AAE7C,QAAM,WAAW,MAAM,eAAe,GAAG,gBAAgB,wBAAwB;AAAA,IAC/E,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU,EAAE,aAAa,QAAQ,CAAC;AAAA,EAC/C,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,IAAI,YAAY,GAAG,SAAS,MAAM,WAAM,IAAI,EAAE;AAAA,EACtD;AAEA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAO,KAAK;AACd;AAMA,eAAsB,eAAe,QAQjB;AAClB,QAAM,QAAQ,OAAO,YAAY,YAAY,MAAM,UAAU,MAAM;AAEnE,QAAM,OAAO;AAAA,IACX,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO;AAAA,IACf,aAAa,OAAO;AAAA,IACpB,WAAW,OAAO;AAAA,IAClB,gBAAgB,OAAO;AAAA,IACvB,uBAAuB,OAAO;AAAA,EAChC;AAEA,QAAM,WAAW,MAAM;AAAA,IACrB,GAAG,gBAAgB,WAAW,MAAM,OAAO;AAAA,IAC3C;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,IAAI,YAAY,GAAG,SAAS,MAAM,WAAM,IAAI,EAAE;AAAA,EACtD;AAEA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAO,KAAK;AACd;AAKA,eAAsB,iBACpB,OACA,QACgC;AAChC,QAAM,YAAY,KAAK,IAAI;AAE3B,SAAO,KAAK,IAAI,IAAI,YAAY,iBAAiB;AAC/C,UAAM,WAAW,MAAM,MAAM,GAAG,gBAAgB,yBAAyB,KAAK,EAAE;AAEhF,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,YAAY,wBAAwB,SAAS,MAAM,WAAM,IAAI,EAAE;AAAA,IAC3E;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,aAAS,KAAK,OAAO,KAAK,aAAa;AAEvC,QAAI,KAAK,UAAU,YAAa,QAAO;AACvC,QAAI,KAAK,UAAU,UAAU;AAC3B,YAAM,IAAI,YAAY,KAAK,SAAS,qCAAqC;AAAA,IAC3E;AAEA,UAAM,MAAM,gBAAgB;AAAA,EAC9B;AAEA,QAAM,IAAI,aAAa;AACzB;;;AExJO,SAAS,aAAa,MAA+B,MAAuB;AACjF,MAAI,MAAM;AACR,WAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,EACrC;AAEA,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,UAAM,QAAQ,IAAI,QAAQ,YAAY,KAAK,EAAE,QAAQ,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;AACjF,UAAM,KAAK,KAAK,KAAK,KAAK,OAAO,KAAK,CAAC,EAAE;AAAA,EAC3C;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,aAAa,SAAiB,MAA+B,MAAqB;AAChG,MAAI,MAAM;AACR,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,EACjE,OAAO;AACL,YAAQ,IAAI;AAAA,EAAK,OAAO;AAAA,CAAI;AAC5B,YAAQ,IAAI,aAAa,MAAM,KAAK,CAAC;AACrC,YAAQ,IAAI;AAAA,EACd;AACF;AAEO,SAAS,WAAW,SAAiB,MAAe,UAAwB;AACjF,MAAI,MAAM;AACR,YAAQ,MAAM,KAAK,UAAU,EAAE,SAAS,OAAO,OAAO,SAAS,SAAS,CAAC,CAAC;AAAA,EAC5E,OAAO;AACL,YAAQ,MAAM;AAAA,SAAY,OAAO;AAAA,CAAI;AAAA,EACvC;AACF;;;ALrBA,eAAsB,OAAO,MAAmC;AAC9D,QAAM,EAAE,MAAM,QAAQ,aAAa,WAAW,SAAS,KAAK,IAAI;AAChE,QAAM,UAAmB,UAAU,YAAY;AAC/C,QAAM,QAAQ,UAAU,MAAM,UAAU,MAAM;AAE9C,MAAI;AAEF,UAAM,gBAAgB,QAAQ,SAAS;AACvC,QAAI;AACF,YAAMC,QAAO,aAAa;AAAA,IAC5B,QAAQ;AACN,iBAAW,oBAAoB,aAAa,IAAI,MAAM,WAAW,WAAW;AAC5E,cAAQ,KAAK,WAAW,WAAW;AAAA,IACrC;AAGA,UAAM,EAAE,QAAAC,SAAQ,MAAM,IAAI,MAAM,mBAAmB;AAEnD,QAAI,CAAC,MAAM;AACT,UAAI,OAAO;AACT,gBAAQ,IAAI;AAAA,kBAAqBA,QAAO,OAAO,EAAE;AACjD,gBAAQ,IAAI,gBAAgBA,QAAO,UAAU,EAAE;AAC/C,gBAAQ,IAAI,qDAAgD;AAAA,MAC9D,OAAO;AACL,gBAAQ,IAAI;AAAA,gBAAmBA,QAAO,OAAO,EAAE;AAAA,MACjD;AAAA,IACF;AAGA,QAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,oBAAoB;AACpD,UAAM,YAAY,MAAM,YAAY,aAAa;AACjD,QAAI,CAAC,KAAM,SAAQ,IAAI,IAAI,UAAU,MAAM,GAAG,EAAE,CAAC,KAAK;AAGtD,QAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,sBAAsB;AACtD,UAAM,QAAQ,MAAM,eAAe;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgBA,QAAO;AAAA,MACvB,uBAAuB;AAAA,MACvB;AAAA,IACF,CAAC;AACD,QAAI,CAAC,KAAM,SAAQ,IAAI,gBAAgB,KAAK,GAAG;AAG/C,QAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,oBAAoB;AACpD,UAAM,SAAS,MAAM,iBAAiB,OAAO,CAAC,OAAO,aAAa;AAChE,UAAI,CAAC,MAAM;AACT,YAAI,WAAW,GAAG;AAChB,kBAAQ,OAAO,MAAM,YAAY,QAAQ,GAAG;AAAA,QAC9C,OAAO;AACL,kBAAQ,OAAO,MAAM,GAAG;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,CAAC;AACD,QAAI,CAAC,KAAM,SAAQ,IAAI,OAAO;AAE9B,UAAM,eAAe,OAAO,gBAAiB;AAC7C,UAAM,aAAa,GAAG,MAAM,UAAU,SAAS,YAAY;AAG3D,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB,OAAO;AAAA,MACxB;AAAA,MACA,eAAeA,QAAO;AAAA,MACtB,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC;AAAA,IACF,CAAC;AAGD,UAAM,aAAsC;AAAA,MAC1C;AAAA,MACA,iBAAiB,OAAO;AAAA,MACxB;AAAA,MACA;AAAA,MACA,SAAS,MAAM;AAAA,MACf,UAAU,GAAG,MAAM,QAAQ,UAAU,YAAY;AAAA,MACjD,SAAS;AAAA,MACT,QAAQA,QAAO;AAAA,IACjB;AAEA,QAAI,OAAO;AACT,iBAAW,aAAaA,QAAO;AAC/B,iBAAW,aAAa;AAAA,IAC1B;AAEA,iBAAa,gCAAgC,YAAY,IAAI;AAAA,EAC/D,SAAS,OAAO;AACd,QAAI,iBAAiB,iBAAiB;AACpC,iBAAW,MAAM,SAAS,MAAM,MAAM,QAAQ;AAC9C,cAAQ,KAAK,MAAM,QAAQ;AAAA,IAC7B;AACA,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,eAAW,SAAS,MAAM,WAAW,OAAO;AAC5C,YAAQ,KAAK,WAAW,OAAO;AAAA,EACjC;AACF;;;AMrGA,eAAsB,OAAO,MAAiC;AAC5D,QAAM,EAAE,SAAS,KAAK,IAAI;AAE1B,QAAM,OAAO,MAAM,WAAW;AAC9B,MAAI,CAAC,MAAM;AACT,eAAW,oDAAoD,MAAM,WAAW,SAAS;AACzF,YAAQ,KAAK,WAAW,SAAS;AAAA,EACnC;AAEA,MAAI,UAAU;AACd,MAAI;AACF,cAAU,MAAM,iBAAiB,KAAK,SAAS,SAAS;AAAA,EAC1D,QAAQ;AAAA,EAER;AAEA,QAAM,SAAkC;AAAA,IACtC,SAAS,KAAK;AAAA,IACd,SAAS,GAAG,OAAO;AAAA,IACnB,WAAW,KAAK;AAAA,EAClB;AAEA,MAAI,SAAS;AACX,WAAO,aAAa,KAAK;AAAA,EAC3B;AAEA,eAAa,eAAe,QAAQ,IAAI;AAC1C;;;AC9BA,eAAsB,OAAO,MAAiC;AAC5D,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,UAAU,MAAM,kBAAkB;AAExC,MAAI,QAAQ,WAAW,GAAG;AACxB,QAAI,MAAM;AACR,cAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC;AAAA,IAC7D,OAAO;AACL,cAAQ,IAAI,6DAA6D;AAAA,IAC3E;AACA;AAAA,EACF;AAEA,MAAI,MAAM;AACR,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,UAAU,QAAQ,GAAG,MAAM,CAAC,CAAC;AACzE;AAAA,EACF;AAEA,UAAQ,IAAI;AAAA,mBAAsB,QAAQ,MAAM;AAAA,CAAM;AACtD,aAAW,UAAU,SAAS;AAC5B,YAAQ,IAAI,KAAK,OAAO,IAAI,KAAK,OAAO,MAAM,GAAG;AACjD,YAAQ,IAAI,iBAAiB,OAAO,YAAY,EAAE;AAClD,YAAQ,IAAI,iBAAiB,OAAO,eAAe,EAAE;AACrD,YAAQ,IAAI,iBAAiB,OAAO,UAAU,EAAE;AAChD,YAAQ,IAAI,iBAAiB,OAAO,OAAO,EAAE;AAC7C,YAAQ,IAAI,iBAAiB,OAAO,UAAU,EAAE;AAChD,YAAQ,IAAI;AAAA,EACd;AACF;;;AClCA,SAAS,UAAAC,eAAc;AAQvB,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AACF;AAOA,eAAsB,MAAM,MAAgC;AAC1D,QAAM,EAAE,SAAS,KAAK,IAAI;AAC1B,QAAM,UAAmB,UAAU,YAAY;AAE/C,MAAI;AACF,UAAM,aAAa,MAAM,WAAW;AACpC,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,cAAc;AAAA,IAC1B;AAGA,UAAM,UAAU,MAAM,iBAAiB,WAAW,SAAS,OAAO;AAClE,QAAI,WAAW,OAAO,MAAM,GAAG;AAC7B,YAAM,IAAI,WAAW,WAAW,OAAO;AAAA,IACzC;AAEA,UAAM,SAAS,MAAM,UAAU,WAAW,YAAY,OAAO;AAC7D,UAAM,KAAK,IAAIC,QAAO,SAAS,0BAA0B,sBAAsB,MAAM;AAGrF,UAAM,YAAY,MAAM,GAAG,SAAS,WAAW,OAAO;AACtD,UAAM,eAAeA,QAAO,YAAY,SAAS;AAEjD,QAAI,cAAc,IAAI;AACpB,mBAAa,oBAAoB;AAAA,QAC/B,WAAW;AAAA,QACX,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF,GAAG,IAAI;AACP;AAAA,IACF;AAEA,QAAI,CAAC,KAAM,SAAQ,IAAI;AAAA,aAAgB,YAAY,MAAM;AACzD,QAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,oCAAoC;AAGpE,UAAM,KAAK,MAAM,GAAG,aAAa,WAAW,SAAS,IAAI;AACzD,QAAI,CAAC,KAAM,SAAQ,IAAI,OAAO,GAAG,IAAI,EAAE;AAEvC,QAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,6BAA6B;AAC7D,UAAM,UAAU,MAAM,GAAG,KAAK;AAC9B,QAAI,CAAC,KAAM,SAAQ,IAAI,YAAY;AAEnC,iBAAa,8BAA8B;AAAA,MACzC,iBAAiB,QAAQ;AAAA,MACzB,SAAS,GAAG,YAAY;AAAA,MACxB,QAAQ,WAAW;AAAA,MACnB;AAAA,IACF,GAAG,IAAI;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,iBAAiB;AACpC,iBAAW,MAAM,SAAS,MAAM,MAAM,QAAQ;AAC9C,cAAQ,KAAK,MAAM,QAAQ;AAAA,IAC7B;AACA,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,eAAW,SAAS,MAAM,WAAW,OAAO;AAC5C,YAAQ,KAAK,WAAW,OAAO;AAAA,EACjC;AACF;;;ATtEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,YAAY,EACjB,YAAY,wDAAwD,EACpE,QAAQ,OAAO;AAGlB,QACG,QAAQ,UAAU,EAAE,WAAW,KAAK,CAAC,EACrC,YAAY,4BAA4B,EACxC,eAAe,iBAAiB,YAAY,EAC5C,eAAe,qBAAqB,cAAc,EAClD,eAAe,wBAAwB,mBAAmB,EAC1D,eAAe,kBAAkB,+BAA+B,EAChE,OAAO,aAAa,4BAA4B,KAAK,EACrD,OAAO,UAAU,+BAA+B,KAAK,EACrD,OAAO,CAAC,SAAS;AAChB,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,QAAQ,KAAK;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK;AAAA,IAChB,SAAS,KAAK;AAAA,IACd,MAAM,KAAK;AAAA,EACb,CAAC;AACH,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,iCAAiC,EAC7C,OAAO,cAAc,oBAAoB,KAAK,EAC9C,OAAO,UAAU,kBAAkB,KAAK,EACxC,OAAO,CAAC,SAAS;AAChB,SAAO,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AACnD,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,sBAAsB,EAClC,OAAO,UAAU,kBAAkB,KAAK,EACxC,OAAO,CAAC,SAAS;AAChB,SAAO,EAAE,MAAM,KAAK,KAAK,CAAC;AAC5B,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,uDAAuD,EACnE,OAAO,aAAa,4BAA4B,KAAK,EACrD,OAAO,UAAU,kBAAkB,KAAK,EACxC,OAAO,CAAC,SAAS;AAChB,QAAM,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AAClD,CAAC;AAEH,QAAQ,MAAM;","names":["access","wallet","readFile","resolve","readFile","access","wallet","ethers","ethers"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/launch.ts","../src/lib/wallet.ts","../src/lib/config.ts","../src/lib/flaunch-api.ts","../src/lib/errors.ts","../src/lib/output.ts","../src/commands/wallet.ts","../src/commands/status.ts","../src/commands/claim.ts","../src/commands/fees.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { Command } from \"commander\";\nimport { launch } from \"./commands/launch.js\";\nimport { wallet } from \"./commands/wallet.js\";\nimport { status } from \"./commands/status.js\";\nimport { claim } from \"./commands/claim.js\";\nimport { fees } from \"./commands/fees.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n .name(\"moltlaunch\")\n .description(\"CLI for AI agents to launch tokens on Base via Flaunch\")\n .version(version);\n\n// Default command: launch a token\nprogram\n .command(\"launch\", { isDefault: true })\n .description(\"Launch a new token on Base\")\n .requiredOption(\"--name <name>\", \"Token name\")\n .requiredOption(\"--symbol <symbol>\", \"Token symbol\")\n .requiredOption(\"--description <desc>\", \"Token description\")\n .requiredOption(\"--image <path>\", \"Path to token image (max 5MB)\")\n .option(\"--testnet\", \"Use Base Sepolia testnet\", false)\n .option(\"--json\", \"Output as JSON (for agents)\", false)\n .action((opts) => {\n launch({\n name: opts.name,\n symbol: opts.symbol,\n description: opts.description,\n imagePath: opts.image,\n testnet: opts.testnet,\n json: opts.json,\n });\n });\n\nprogram\n .command(\"wallet\")\n .description(\"Show wallet address and balance\")\n .option(\"--show-key\", \"Show private key\", false)\n .option(\"--json\", \"Output as JSON\", false)\n .action((opts) => {\n wallet({ showKey: opts.showKey, json: opts.json });\n });\n\nprogram\n .command(\"status\")\n .description(\"List launched tokens\")\n .option(\"--json\", \"Output as JSON\", false)\n .action((opts) => {\n status({ json: opts.json });\n });\n\nprogram\n .command(\"fees\")\n .description(\"Check claimable fee balance (read-only, no gas needed)\")\n .option(\"--testnet\", \"Use Base Sepolia testnet\", false)\n .option(\"--json\", \"Output as JSON\", false)\n .action((opts) => {\n fees({ testnet: opts.testnet, json: opts.json });\n });\n\nprogram\n .command(\"claim\")\n .description(\"Withdraw accumulated fees from PositionManager escrow\")\n .option(\"--testnet\", \"Use Base Sepolia testnet\", false)\n .option(\"--json\", \"Output as JSON\", false)\n .action((opts) => {\n claim({ testnet: opts.testnet, json: opts.json });\n });\n\nprogram.parse();\n","import { resolve } from \"node:path\";\nimport { access } from \"node:fs/promises\";\nimport { loadOrCreateWallet, saveLaunchRecord } from \"../lib/wallet.js\";\nimport { uploadImage, launchMemecoin, pollLaunchStatus } from \"../lib/flaunch-api.js\";\nimport { printSuccess, printError } from \"../lib/output.js\";\nimport { CHAIN, REVENUE_MANAGER_ADDRESS } from \"../lib/config.js\";\nimport { MoltlaunchError, EXIT_CODES } from \"../lib/errors.js\";\nimport type { LaunchParams, Network } from \"../types.js\";\n\nexport async function launch(opts: LaunchParams): Promise<void> {\n const { name, symbol, description, imagePath, testnet, json } = opts;\n const network: Network = testnet ? \"testnet\" : \"mainnet\";\n const chain = testnet ? CHAIN.testnet : CHAIN.mainnet;\n\n try {\n // Validate image exists\n const resolvedImage = resolve(imagePath);\n try {\n await access(resolvedImage);\n } catch {\n printError(`Image not found: ${resolvedImage}`, json, EXIT_CODES.UPLOAD_FAIL);\n process.exit(EXIT_CODES.UPLOAD_FAIL);\n }\n\n // Step 1: Load or create wallet\n const { wallet, isNew } = await loadOrCreateWallet();\n\n if (!json) {\n if (isNew) {\n console.log(`\\nWallet created: ${wallet.address}`);\n console.log(`Private key: ${wallet.privateKey}`);\n console.log(\"(Save this key — it will not be shown again)\\n\");\n } else {\n console.log(`\\nUsing wallet: ${wallet.address}`);\n }\n }\n\n // Step 2: Upload image to IPFS\n if (!json) process.stdout.write(\"Uploading image...\");\n const imageIpfs = await uploadImage(resolvedImage);\n if (!json) console.log(` ${imageIpfs.slice(0, 16)}...`);\n\n // Step 3: Launch via Flaunch Web2 API (gasless — Flaunch handles on-chain tx)\n if (!json) process.stdout.write(\"Submitting launch...\");\n const jobId = await launchMemecoin({\n name,\n symbol,\n description,\n imageIpfs,\n creatorAddress: wallet.address,\n revenueManagerAddress: REVENUE_MANAGER_ADDRESS,\n network,\n });\n if (!json) console.log(` queued (job ${jobId})`);\n\n // Step 4: Poll for completion\n if (!json) process.stdout.write(\"Deploying on-chain\");\n const result = await pollLaunchStatus(jobId, (state, position) => {\n if (!json) {\n if (position > 0) {\n process.stdout.write(` [queue: ${position}]`);\n } else {\n process.stdout.write(\".\");\n }\n }\n });\n if (!json) console.log(\" done\");\n\n const tokenAddress = result.collectionToken!.address;\n const flaunchUrl = `${chain.flaunchUrl}/coin/${tokenAddress}`;\n\n // Step 5: Save launch record\n await saveLaunchRecord({\n name,\n symbol,\n tokenAddress,\n transactionHash: result.transactionHash!,\n network,\n walletAddress: wallet.address,\n launchedAt: new Date().toISOString(),\n flaunchUrl,\n });\n\n // Output result\n const outputData: Record<string, unknown> = {\n tokenAddress,\n transactionHash: result.transactionHash,\n name,\n symbol,\n network: chain.name,\n explorer: `${chain.explorer}/token/${tokenAddress}`,\n flaunch: flaunchUrl,\n wallet: wallet.address,\n };\n\n if (isNew) {\n outputData.privateKey = wallet.privateKey;\n outputData.walletNote = \"Save this private key — it will not be shown again\";\n }\n\n printSuccess(\"Token launched successfully!\", outputData, json);\n } catch (error) {\n if (error instanceof MoltlaunchError) {\n printError(error.message, json, error.exitCode);\n process.exit(error.exitCode);\n }\n const message = error instanceof Error ? error.message : String(error);\n printError(message, json, EXIT_CODES.GENERAL);\n process.exit(EXIT_CODES.GENERAL);\n }\n}\n","import { ethers } from \"ethers\";\nimport { readFile, writeFile, mkdir, chmod, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { WALLET_DIR, WALLET_FILE, LAUNCHES_FILE, CHAIN } from \"./config.js\";\nimport type { WalletData, LaunchRecord, Network } from \"../types.js\";\n\nfunction getWalletDir(): string {\n return join(homedir(), WALLET_DIR);\n}\n\nfunction getWalletPath(): string {\n return join(getWalletDir(), WALLET_FILE);\n}\n\nfunction getLaunchesPath(): string {\n return join(getWalletDir(), LAUNCHES_FILE);\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function walletExists(): Promise<boolean> {\n return fileExists(getWalletPath());\n}\n\nexport async function loadWallet(): Promise<WalletData | null> {\n const path = getWalletPath();\n if (!(await fileExists(path))) return null;\n\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw) as WalletData;\n}\n\nexport async function createWallet(): Promise<WalletData> {\n const wallet = ethers.Wallet.createRandom();\n const data: WalletData = {\n address: wallet.address,\n privateKey: wallet.privateKey,\n createdAt: new Date().toISOString(),\n };\n\n const dir = getWalletDir();\n await mkdir(dir, { recursive: true });\n\n const path = getWalletPath();\n await writeFile(path, JSON.stringify(data, null, 2), { mode: 0o600 });\n await chmod(path, 0o600);\n\n return data;\n}\n\nexport async function loadOrCreateWallet(): Promise<{ wallet: WalletData; isNew: boolean }> {\n const existing = await loadWallet();\n if (existing) return { wallet: existing, isNew: false };\n\n const wallet = await createWallet();\n return { wallet, isNew: true };\n}\n\nexport async function getWalletBalance(address: string, network: Network): Promise<string> {\n const chain = network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n const provider = new ethers.JsonRpcProvider(chain.rpcUrl);\n const balance = await provider.getBalance(address);\n return ethers.formatEther(balance);\n}\n\nexport async function getSigner(privateKey: string, network: Network): Promise<ethers.Wallet> {\n const chain = network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n const provider = new ethers.JsonRpcProvider(chain.rpcUrl);\n return new ethers.Wallet(privateKey, provider);\n}\n\nexport async function saveLaunchRecord(record: LaunchRecord): Promise<void> {\n const path = getLaunchesPath();\n let records: LaunchRecord[] = [];\n\n if (await fileExists(path)) {\n const raw = await readFile(path, \"utf-8\");\n records = JSON.parse(raw) as LaunchRecord[];\n }\n\n records.push(record);\n\n const dir = getWalletDir();\n await mkdir(dir, { recursive: true });\n await writeFile(path, JSON.stringify(records, null, 2), { mode: 0o600 });\n}\n\nexport async function loadLaunchRecords(): Promise<LaunchRecord[]> {\n const path = getLaunchesPath();\n if (!(await fileExists(path))) return [];\n\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw) as LaunchRecord[];\n}\n","export const REVENUE_MANAGER_ADDRESS = \"0x3Bc08524d9DaaDEC9d1Af87818d809611F0fD669\";\n\n// Flaunch PositionManager — fees accumulate here in escrow\nexport const POSITION_MANAGER_ADDRESS = \"0x51Bba15255406Cfe7099a42183302640ba7dAFDC\";\n\nexport const FLAUNCH_API_BASE = \"https://web2-api.flaunch.gg\";\n\nexport const CHAIN = {\n mainnet: {\n id: 8453,\n name: \"Base\",\n network: \"base\",\n rpcUrl: \"https://mainnet.base.org\",\n explorer: \"https://basescan.org\",\n flaunchUrl: \"https://flaunch.gg/base\",\n },\n testnet: {\n id: 84532,\n name: \"Base Sepolia\",\n network: \"base-sepolia\",\n rpcUrl: \"https://sepolia.base.org\",\n explorer: \"https://sepolia.basescan.org\",\n flaunchUrl: \"https://flaunch.gg/base-sepolia\",\n },\n} as const;\n\nexport const WALLET_DIR = \".moltlaunch\";\nexport const WALLET_FILE = \"wallet.json\";\nexport const LAUNCHES_FILE = \"launches.json\";\n\nexport const MAX_IMAGE_SIZE_BYTES = 5 * 1024 * 1024; // 5MB\nexport const POLL_INTERVAL_MS = 2000;\nexport const POLL_TIMEOUT_MS = 120_000;\n","import { readFile, stat } from \"node:fs/promises\";\nimport {\n FLAUNCH_API_BASE,\n CHAIN,\n MAX_IMAGE_SIZE_BYTES,\n POLL_INTERVAL_MS,\n POLL_TIMEOUT_MS,\n} from \"./config.js\";\nimport { UploadError, LaunchError, TimeoutError } from \"./errors.js\";\nimport type {\n Network,\n FlaunchUploadResponse,\n FlaunchLaunchResponse,\n FlaunchStatusResponse,\n} from \"../types.js\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function fetchWithRetry(\n url: string,\n options: RequestInit,\n retries = 3,\n): Promise<Response> {\n for (let attempt = 0; attempt < retries; attempt++) {\n const response = await fetch(url, options);\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : 2000 * (attempt + 1);\n await sleep(waitMs);\n continue;\n }\n\n return response;\n }\n\n throw new Error(\"Max retries exceeded (429 rate limit)\");\n}\n\n/**\n * Upload image to IPFS via Flaunch Web2 API.\n * Reads file as base64 data URL, returns IPFS hash.\n */\nexport async function uploadImage(imagePath: string): Promise<string> {\n const fileStat = await stat(imagePath);\n if (fileStat.size > MAX_IMAGE_SIZE_BYTES) {\n throw new UploadError(`Image exceeds 5MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)}MB)`);\n }\n\n const imageBuffer = await readFile(imagePath);\n const base64 = imageBuffer.toString(\"base64\");\n\n const ext = imagePath.split(\".\").pop()?.toLowerCase();\n const mimeMap: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n };\n const mime = mimeMap[ext ?? \"\"] ?? \"image/png\";\n const dataUrl = `data:${mime};base64,${base64}`;\n\n const response = await fetchWithRetry(`${FLAUNCH_API_BASE}/api/v1/upload-image`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ base64Image: dataUrl }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new UploadError(`${response.status} — ${text}`);\n }\n\n const data = (await response.json()) as FlaunchUploadResponse;\n return data.ipfsHash;\n}\n\n/**\n * Launch a memecoin via Flaunch Web2 API.\n * This is gasless — Flaunch handles the on-chain transaction server-side.\n */\nexport async function launchMemecoin(params: {\n name: string;\n symbol: string;\n description: string;\n imageIpfs: string;\n creatorAddress: string;\n revenueManagerAddress?: string;\n network: Network;\n}): Promise<string> {\n const chain = params.network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n\n const body = {\n name: params.name,\n symbol: params.symbol,\n description: params.description,\n imageIpfs: params.imageIpfs,\n creatorAddress: params.creatorAddress,\n revenueManagerAddress: params.revenueManagerAddress,\n };\n\n const response = await fetchWithRetry(\n `${FLAUNCH_API_BASE}/api/v1/${chain.network}/launch-memecoin`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new LaunchError(`${response.status} — ${text}`);\n }\n\n const data = (await response.json()) as FlaunchLaunchResponse;\n return data.jobId;\n}\n\n/**\n * Poll launch status until completed or failed.\n */\nexport async function pollLaunchStatus(\n jobId: string,\n onPoll?: (state: string, position: number) => void,\n): Promise<FlaunchStatusResponse> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n const response = await fetch(`${FLAUNCH_API_BASE}/api/v1/launch-status/${jobId}`);\n\n if (!response.ok) {\n const text = await response.text();\n throw new LaunchError(`Status check failed: ${response.status} — ${text}`);\n }\n\n const data = (await response.json()) as FlaunchStatusResponse;\n onPoll?.(data.state, data.queuePosition);\n\n if (data.state === \"completed\") return data;\n if (data.state === \"failed\") {\n throw new LaunchError(data.error ?? \"Launch failed with no error message\");\n }\n\n await sleep(POLL_INTERVAL_MS);\n }\n\n throw new TimeoutError();\n}\n","export const EXIT_CODES = {\n SUCCESS: 0,\n GENERAL: 1,\n NO_WALLET: 2,\n UPLOAD_FAIL: 3,\n LAUNCH_FAIL: 4,\n TIMEOUT: 5,\n NO_GAS: 6,\n} as const;\n\nexport class MoltlaunchError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number,\n ) {\n super(message);\n this.name = \"MoltlaunchError\";\n }\n}\n\nexport class NoWalletError extends MoltlaunchError {\n constructor() {\n super(\"No wallet found. Run `moltlaunch` to create one.\", EXIT_CODES.NO_WALLET);\n }\n}\n\nexport class UploadError extends MoltlaunchError {\n constructor(detail: string) {\n super(`Image upload failed: ${detail}`, EXIT_CODES.UPLOAD_FAIL);\n }\n}\n\nexport class LaunchError extends MoltlaunchError {\n constructor(detail: string) {\n super(`Token launch failed: ${detail}`, EXIT_CODES.LAUNCH_FAIL);\n }\n}\n\nexport class TimeoutError extends MoltlaunchError {\n constructor() {\n super(\"Launch timed out waiting for confirmation.\", EXIT_CODES.TIMEOUT);\n }\n}\n\nexport class NoGasError extends MoltlaunchError {\n constructor(address: string) {\n super(\n `Wallet ${address} has no ETH for gas. Send Base ETH to this address and retry.`,\n EXIT_CODES.NO_GAS,\n );\n }\n}\n","export function formatOutput(data: Record<string, unknown>, json: boolean): string {\n if (json) {\n return JSON.stringify(data, null, 2);\n }\n\n const lines: string[] = [];\n for (const [key, value] of Object.entries(data)) {\n if (value === undefined || value === null) continue;\n const label = key.replace(/([A-Z])/g, \" $1\").replace(/^./, (s) => s.toUpperCase());\n lines.push(` ${label}: ${String(value)}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function printSuccess(message: string, data: Record<string, unknown>, json: boolean): void {\n if (json) {\n console.log(JSON.stringify({ success: true, ...data }, null, 2));\n } else {\n console.log(`\\n${message}\\n`);\n console.log(formatOutput(data, false));\n console.log();\n }\n}\n\nexport function printError(message: string, json: boolean, exitCode: number): void {\n if (json) {\n console.error(JSON.stringify({ success: false, error: message, exitCode }));\n } else {\n console.error(`\\nError: ${message}\\n`);\n }\n}\n","import { loadWallet, getWalletBalance } from \"../lib/wallet.js\";\nimport { printSuccess, printError } from \"../lib/output.js\";\nimport { EXIT_CODES } from \"../lib/errors.js\";\n\ninterface WalletOpts {\n showKey: boolean;\n json: boolean;\n}\n\nexport async function wallet(opts: WalletOpts): Promise<void> {\n const { showKey, json } = opts;\n\n const data = await loadWallet();\n if (!data) {\n printError(\"No wallet found. Run `moltlaunch` to create one.\", json, EXIT_CODES.NO_WALLET);\n process.exit(EXIT_CODES.NO_WALLET);\n }\n\n let balance = \"unknown\";\n try {\n balance = await getWalletBalance(data.address, \"mainnet\");\n } catch {\n // RPC may be unreachable\n }\n\n const output: Record<string, unknown> = {\n address: data.address,\n balance: json ? balance : `${balance} ETH (Base)`,\n network: json ? \"Base\" : undefined,\n createdAt: data.createdAt,\n };\n\n if (showKey) {\n output.privateKey = data.privateKey;\n }\n\n printSuccess(\"Wallet info\", output, json);\n}\n","import { loadLaunchRecords } from \"../lib/wallet.js\";\n\ninterface StatusOpts {\n json: boolean;\n}\n\nexport async function status(opts: StatusOpts): Promise<void> {\n const { json } = opts;\n const records = await loadLaunchRecords();\n\n if (records.length === 0) {\n if (json) {\n console.log(JSON.stringify({ success: true, launches: [] }));\n } else {\n console.log(\"\\nNo tokens launched yet. Run `moltlaunch` to launch one.\\n\");\n }\n return;\n }\n\n if (json) {\n console.log(JSON.stringify({ success: true, launches: records }, null, 2));\n return;\n }\n\n console.log(`\\nLaunched tokens (${records.length}):\\n`);\n for (const record of records) {\n console.log(` ${record.name} (${record.symbol})`);\n console.log(` Token: ${record.tokenAddress}`);\n console.log(` TX: ${record.transactionHash}`);\n console.log(` Flaunch: ${record.flaunchUrl}`);\n console.log(` Network: ${record.network}`);\n console.log(` Launched: ${record.launchedAt}`);\n console.log();\n }\n}\n","import { ethers } from \"ethers\";\nimport { loadWallet, getSigner, getWalletBalance } from \"../lib/wallet.js\";\nimport { POSITION_MANAGER_ADDRESS } from \"../lib/config.js\";\nimport { printSuccess, printError } from \"../lib/output.js\";\nimport { EXIT_CODES, NoWalletError, NoGasError, MoltlaunchError } from \"../lib/errors.js\";\nimport type { Network } from \"../types.js\";\n\n// Fees accumulate in escrow on the PositionManager, not on the Revenue Manager\nconst POSITION_MANAGER_ABI = [\n \"function balances(address) external view returns (uint256)\",\n \"function withdrawFees(address _recipient, bool _unwrap) external\",\n];\n\ninterface ClaimOpts {\n testnet: boolean;\n json: boolean;\n}\n\nexport async function claim(opts: ClaimOpts): Promise<void> {\n const { testnet, json } = opts;\n const network: Network = testnet ? \"testnet\" : \"mainnet\";\n\n try {\n const walletData = await loadWallet();\n if (!walletData) {\n throw new NoWalletError();\n }\n\n // Check gas balance\n const balance = await getWalletBalance(walletData.address, network);\n if (parseFloat(balance) === 0) {\n throw new NoGasError(walletData.address);\n }\n\n const signer = await getSigner(walletData.privateKey, network);\n const pm = new ethers.Contract(POSITION_MANAGER_ADDRESS, POSITION_MANAGER_ABI, signer);\n\n // Check claimable balance\n const claimable = await pm.balances(walletData.address);\n const claimableEth = ethers.formatEther(claimable);\n\n if (claimable === 0n) {\n printSuccess(\"No fees to claim\", {\n claimable: \"0 ETH\",\n wallet: walletData.address,\n network,\n }, json);\n return;\n }\n\n if (!json) console.log(`\\nClaimable: ${claimableEth} ETH`);\n if (!json) process.stdout.write(\"Submitting withdraw transaction...\");\n\n // withdrawFees sends to _recipient, _unwrap=true converts flETH→ETH\n const tx = await pm.withdrawFees(walletData.address, true);\n if (!json) console.log(` tx ${tx.hash}`);\n\n if (!json) process.stdout.write(\"Waiting for confirmation...\");\n const receipt = await tx.wait();\n if (!json) console.log(\" confirmed\");\n\n printSuccess(\"Fees claimed successfully!\", {\n transactionHash: receipt.hash,\n claimed: `${claimableEth} ETH`,\n wallet: walletData.address,\n network,\n }, json);\n } catch (error) {\n if (error instanceof MoltlaunchError) {\n printError(error.message, json, error.exitCode);\n process.exit(error.exitCode);\n }\n const message = error instanceof Error ? error.message : String(error);\n printError(message, json, EXIT_CODES.GENERAL);\n process.exit(EXIT_CODES.GENERAL);\n }\n}\n","import { ethers } from \"ethers\";\nimport { loadWallet, getWalletBalance } from \"../lib/wallet.js\";\nimport { POSITION_MANAGER_ADDRESS, CHAIN } from \"../lib/config.js\";\nimport { printSuccess, printError } from \"../lib/output.js\";\nimport { EXIT_CODES, NoWalletError, MoltlaunchError } from \"../lib/errors.js\";\nimport type { Network } from \"../types.js\";\n\nconst POSITION_MANAGER_ABI = [\n \"function balances(address) external view returns (uint256)\",\n];\n\ninterface FeesOpts {\n testnet: boolean;\n json: boolean;\n}\n\nexport async function fees(opts: FeesOpts): Promise<void> {\n const { testnet, json } = opts;\n const network: Network = testnet ? \"testnet\" : \"mainnet\";\n\n try {\n const walletData = await loadWallet();\n if (!walletData) {\n throw new NoWalletError();\n }\n\n const chain = testnet ? CHAIN.testnet : CHAIN.mainnet;\n const provider = new ethers.JsonRpcProvider(chain.rpcUrl);\n const pm = new ethers.Contract(POSITION_MANAGER_ADDRESS, POSITION_MANAGER_ABI, provider);\n\n const claimable = await pm.balances(walletData.address);\n const claimableEth = ethers.formatEther(claimable);\n\n const walletBalance = await getWalletBalance(walletData.address, network);\n const hasGas = parseFloat(walletBalance) > 0;\n\n printSuccess(\"Fee balance\", {\n claimable: `${claimableEth} ETH`,\n wallet: walletData.address,\n walletBalance: `${walletBalance} ETH`,\n hasGas,\n network: chain.name,\n canClaim: hasGas && claimable > 0n,\n }, json);\n } catch (error) {\n if (error instanceof MoltlaunchError) {\n printError(error.message, json, error.exitCode);\n process.exit(error.exitCode);\n }\n const message = error instanceof Error ? error.message : String(error);\n printError(message, json, EXIT_CODES.GENERAL);\n process.exit(EXIT_CODES.GENERAL);\n }\n}\n"],"mappings":"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","names":["access","wallet","readFile","resolve","readFile","access","wallet","ethers","ethers","ethers","POSITION_MANAGER_ABI","ethers","require"]}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "moltlaunch",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "CLI for AI agents to launch tokens on Base via Flaunch",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/nikshepsvn/moltlaunch.git"
7
+ "url": "git+https://github.com/nikshepsvn/moltlaunch.git"
8
8
  },
9
9
  "homepage": "https://github.com/nikshepsvn/moltlaunch#readme",
10
10
  "type": "module",
11
11
  "bin": {
12
- "moltlaunch": "./dist/index.js"
12
+ "moltlaunch": "dist/index.js"
13
13
  },
14
14
  "files": [
15
15
  "dist",