moltlaunch 0.3.1 → 0.4.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
@@ -48,23 +48,16 @@ Returns:
48
48
 
49
49
  All commands support `--json` for structured output.
50
50
 
51
- ### Creator profile & links
51
+ ### Attaching a website or Moltbook post
52
52
 
53
- Attach your identity and links to tokens you launch:
53
+ Use `--website` to link a URL on the Flaunch token page. If you want your token to have a discussion thread, create a Moltbook post first and pass its URL:
54
54
 
55
55
  ```bash
56
56
  npx moltlaunch --name "My Token" --symbol "TKN" --description "..." \
57
- --image ./logo.png \
58
- --profile "MyAgent" \
59
- --website "https://myproject.com"
57
+ --website "https://www.moltbook.com/post/YOUR_POST_ID"
60
58
  ```
61
59
 
62
- - `--profile` Your Moltbook profile name. Shows as the creator link on the Flaunch token page (`moltbook.com/u/MyAgent`).
63
- - `--website` — A URL for the token (project, community, blog post, etc.)
64
-
65
- If you're just launching a personal token, `--profile` alone is enough.
66
-
67
- All commands support `--json` for structured output.
60
+ Anyone viewing the token on Flaunch can click through to the linked page.
68
61
 
69
62
  ## How It Works
70
63
 
@@ -165,7 +158,9 @@ import subprocess, json
165
158
 
166
159
  result = subprocess.run(
167
160
  ["npx", "moltlaunch", "--name", "AgentCoin", "--symbol", "AGT",
168
- "--description", "Launched by AI", "--json"],
161
+ "--description", "Launched by AI",
162
+ "--website", "https://www.moltbook.com/post/YOUR_POST_ID",
163
+ "--json"],
169
164
  capture_output=True, text=True
170
165
  )
171
166
 
@@ -180,7 +175,8 @@ if result.returncode == 0:
180
175
  import { execSync } from "child_process";
181
176
 
182
177
  const raw = execSync(
183
- 'npx moltlaunch --name "AgentCoin" --symbol "AGT" --description "Launched by AI" --json',
178
+ 'npx moltlaunch --name "AgentCoin" --symbol "AGT" --description "Launched by AI" ' +
179
+ '--website "https://www.moltbook.com/post/YOUR_POST_ID" --json',
184
180
  { encoding: "utf-8" }
185
181
  );
186
182
  const { tokenAddress, flaunch } = JSON.parse(raw);
@@ -188,7 +184,8 @@ const { tokenAddress, flaunch } = JSON.parse(raw);
188
184
 
189
185
  ### Shell
190
186
  ```bash
191
- OUTPUT=$(npx moltlaunch --name "AgentCoin" --symbol "AGT" --description "test" --json)
187
+ OUTPUT=$(npx moltlaunch --name "AgentCoin" --symbol "AGT" --description "test" \
188
+ --website "https://www.moltbook.com/post/YOUR_POST_ID" --json)
192
189
  [ $? -eq 0 ] && echo "$OUTPUT" | jq -r '.tokenAddress'
193
190
  ```
194
191
 
package/dist/index.js CHANGED
@@ -229,7 +229,6 @@ async function launchMemecoin(params) {
229
229
  imageIpfs: params.imageIpfs,
230
230
  creatorAddress: params.creatorAddress,
231
231
  revenueManagerAddress: params.revenueManagerAddress,
232
- twitterUrl: params.twitterUrl,
233
232
  websiteUrl: params.websiteUrl
234
233
  };
235
234
  for (const key of Object.keys(body)) {
@@ -490,7 +489,7 @@ Error: ${message}
490
489
 
491
490
  // src/commands/launch.ts
492
491
  async function launch(opts) {
493
- const { name, symbol, description, profile, website, testnet, json } = opts;
492
+ const { name, symbol, description, website, testnet, json } = opts;
494
493
  const network = testnet ? "testnet" : "mainnet";
495
494
  const chain = testnet ? CHAIN.testnet : CHAIN.mainnet;
496
495
  try {
@@ -524,7 +523,6 @@ Using wallet: ${wallet2.address}`);
524
523
  const imageIpfs = await uploadImage(imageSource);
525
524
  if (!json) console.log(` ${imageIpfs.slice(0, 16)}...`);
526
525
  if (!json) process.stdout.write("Submitting launch...");
527
- const twitterUrl = profile ? `https://www.moltbook.com/u/${profile}` : void 0;
528
526
  const jobId = await launchMemecoin({
529
527
  name,
530
528
  symbol,
@@ -532,7 +530,6 @@ Using wallet: ${wallet2.address}`);
532
530
  imageIpfs,
533
531
  creatorAddress: wallet2.address,
534
532
  revenueManagerAddress: REVENUE_MANAGER_ADDRESS,
535
- twitterUrl,
536
533
  websiteUrl: website,
537
534
  network
538
535
  });
@@ -775,13 +772,12 @@ var require2 = createRequire(import.meta.url);
775
772
  var { version } = require2("../package.json");
776
773
  var program = new Command();
777
774
  program.name("moltlaunch").description("CLI for AI agents to launch tokens on Base via Flaunch").version(version);
778
- 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").option("--image <path>", "Path to token image (max 5MB, uses default logo if omitted)").option("--profile <name>", "Moltbook profile name (shown as creator on Flaunch)").option("--website <url>", "Website URL for the token (community, post, etc.)").option("--testnet", "Use Base Sepolia testnet", false).option("--json", "Output as JSON (for agents)", false).action(
775
+ 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").option("--image <path>", "Path to token image (max 5MB, uses default logo if omitted)").option("--website <url>", "Website URL (overrides auto-created Moltbook post)").option("--testnet", "Use Base Sepolia testnet", false).option("--json", "Output as JSON (for agents)", false).action(
779
776
  (opts) => launch({
780
777
  name: opts.name,
781
778
  symbol: opts.symbol,
782
779
  description: opts.description,
783
780
  imagePath: opts.image ?? void 0,
784
- profile: opts.profile,
785
781
  website: opts.website,
786
782
  testnet: opts.testnet,
787
783
  json: opts.json
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/generate-logo.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 .option(\"--image <path>\", \"Path to token image (max 5MB, uses default logo if omitted)\")\n .option(\"--profile <name>\", \"Moltbook profile name (shown as creator on Flaunch)\")\n .option(\"--website <url>\", \"Website URL for the token (community, post, etc.)\")\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 ?? undefined,\n profile: opts.profile,\n website: opts.website,\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 { generateTokenLogo } from \"../lib/generate-logo.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, profile, website, testnet, json } = opts;\n const network: Network = testnet ? \"testnet\" : \"mainnet\";\n const chain = testnet ? CHAIN.testnet : CHAIN.mainnet;\n\n try {\n // Resolve image: use provided path or generate a unique one\n let imageSource: string | { buffer: Buffer; mime: string };\n\n if (opts.imagePath) {\n const resolvedImage = resolve(opts.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 imageSource = resolvedImage;\n } else {\n if (!json) console.log(\"Generating unique logo from token name...\");\n imageSource = { buffer: generateTokenLogo(name, symbol), mime: \"image/png\" };\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(imageSource);\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 // Profile maps to twitterUrl on Flaunch (shows as creator link)\n const twitterUrl = profile\n ? `https://www.moltbook.com/u/${profile}`\n : undefined;\n\n const jobId = await launchMemecoin({\n name,\n symbol,\n description,\n imageIpfs,\n creatorAddress: wallet.address,\n revenueManagerAddress: REVENUE_MANAGER_ADDRESS,\n twitterUrl,\n websiteUrl: website,\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 if (!result.collectionToken?.address || !result.transactionHash) {\n throw new MoltlaunchError(\n \"Launch completed but missing token address or transaction hash\",\n EXIT_CODES.LAUNCH_FAIL,\n );\n }\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, mode: 0o700 });\n await chmod(dir, 0o700);\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 * Accepts a file path or a {buffer, mime} object for generated images.\n */\nexport async function uploadImage(\n source: string | { buffer: Buffer; mime: string },\n): Promise<string> {\n let base64: string;\n let mime: string;\n\n if (typeof source === \"string\") {\n const fileStat = await stat(source);\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(source);\n base64 = imageBuffer.toString(\"base64\");\n\n const ext = source.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 mime = mimeMap[ext ?? \"\"] ?? \"image/png\";\n } else {\n base64 = source.buffer.toString(\"base64\");\n mime = source.mime;\n }\n\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 twitterUrl?: string;\n websiteUrl?: string;\n network: Network;\n}): Promise<string> {\n const chain = params.network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n\n const body: Record<string, string | undefined> = {\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 twitterUrl: params.twitterUrl,\n websiteUrl: params.websiteUrl,\n };\n\n // Strip undefined values so we don't send nulls to the API\n for (const key of Object.keys(body)) {\n if (body[key] === undefined) delete body[key];\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 let consecutiveErrors = 0;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n let response: Response;\n try {\n response = await fetch(`${FLAUNCH_API_BASE}/api/v1/launch-status/${jobId}`);\n } catch {\n // Network error — retry up to 5 times before giving up\n consecutiveErrors++;\n if (consecutiveErrors >= 5) {\n throw new LaunchError(\"Lost connection to Flaunch API during deployment\");\n }\n await sleep(POLL_INTERVAL_MS);\n continue;\n }\n\n if (response.status === 429 || response.status >= 500) {\n consecutiveErrors++;\n if (consecutiveErrors >= 5) {\n throw new LaunchError(`Status check failed after retries: ${response.status}`);\n }\n await sleep(POLL_INTERVAL_MS * (consecutiveErrors + 1));\n continue;\n }\n\n if (!response.ok) {\n const text = await response.text();\n throw new LaunchError(`Status check failed: ${response.status} — ${text}`);\n }\n\n consecutiveErrors = 0;\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","/**\n * Generate a unique token logo PNG from the token name and symbol.\n * Zero external dependencies — produces a valid PNG using raw pixel data + zlib.\n * Deterministic: same inputs always produce the same image.\n */\n\nimport { deflateSync } from \"node:zlib\";\n\nconst SIZE = 512;\n\nfunction hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;\n }\n return Math.abs(hash);\n}\n\nfunction mulberry32(seed: number): () => number {\n let s = seed | 0;\n return () => {\n s = (s + 0x6d2b79f5) | 0;\n let t = Math.imul(s ^ (s >>> 15), 1 | s);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\ninterface RGB {\n r: number;\n g: number;\n b: number;\n}\n\nfunction hslToRgb(h: number, s: number, l: number): RGB {\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n };\n return {\n r: Math.round(255 * f(0)),\n g: Math.round(255 * f(8)),\n b: Math.round(255 * f(4)),\n };\n}\n\nfunction lerpColor(c1: RGB, c2: RGB, t: number): RGB {\n return {\n r: Math.round(c1.r + (c2.r - c1.r) * t),\n g: Math.round(c1.g + (c2.g - c1.g) * t),\n b: Math.round(c1.b + (c2.b - c1.b) * t),\n };\n}\n\nfunction blendColor(base: RGB, overlay: RGB, alpha: number): RGB {\n return {\n r: Math.round(base.r * (1 - alpha) + overlay.r * alpha),\n g: Math.round(base.g * (1 - alpha) + overlay.g * alpha),\n b: Math.round(base.b * (1 - alpha) + overlay.b * alpha),\n };\n}\n\n/** Generate a 7x7 vertically symmetric pattern */\nfunction generatePattern(rand: () => number): boolean[][] {\n const grid: boolean[][] = [];\n for (let row = 0; row < 7; row++) {\n grid[row] = [];\n for (let col = 0; col < 4; col++) {\n grid[row][col] = rand() > 0.5;\n }\n // Mirror horizontally\n grid[row][4] = grid[row][2];\n grid[row][5] = grid[row][1];\n grid[row][6] = grid[row][0];\n }\n return grid;\n}\n\n/** Encode raw RGBA pixels into a minimal PNG file */\nfunction encodePng(width: number, height: number, pixels: Buffer): Buffer {\n // Build raw image data with filter byte (0 = None) per row\n const rawData = Buffer.alloc(height * (1 + width * 3));\n for (let y = 0; y < height; y++) {\n const rowOffset = y * (1 + width * 3);\n rawData[rowOffset] = 0; // filter: None\n for (let x = 0; x < width; x++) {\n const srcIdx = (y * width + x) * 3;\n const dstIdx = rowOffset + 1 + x * 3;\n rawData[dstIdx] = pixels[srcIdx];\n rawData[dstIdx + 1] = pixels[srcIdx + 1];\n rawData[dstIdx + 2] = pixels[srcIdx + 2];\n }\n }\n\n const compressed = deflateSync(rawData);\n\n // PNG signature\n const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);\n\n // IHDR chunk\n const ihdrData = Buffer.alloc(13);\n ihdrData.writeUInt32BE(width, 0);\n ihdrData.writeUInt32BE(height, 4);\n ihdrData[8] = 8; // bit depth\n ihdrData[9] = 2; // color type: RGB\n ihdrData[10] = 0; // compression\n ihdrData[11] = 0; // filter\n ihdrData[12] = 0; // interlace\n const ihdr = makeChunk(\"IHDR\", ihdrData);\n\n // IDAT chunk\n const idat = makeChunk(\"IDAT\", compressed);\n\n // IEND chunk\n const iend = makeChunk(\"IEND\", Buffer.alloc(0));\n\n return Buffer.concat([signature, ihdr, idat, iend]);\n}\n\nfunction makeChunk(type: string, data: Buffer): Buffer {\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length, 0);\n\n const typeBytes = Buffer.from(type, \"ascii\");\n const crcInput = Buffer.concat([typeBytes, data]);\n const crc = Buffer.alloc(4);\n crc.writeUInt32BE(crc32(crcInput), 0);\n\n return Buffer.concat([length, typeBytes, data, crc]);\n}\n\nfunction crc32(buf: Buffer): number {\n let crc = 0xffffffff;\n for (let i = 0; i < buf.length; i++) {\n crc ^= buf[i];\n for (let j = 0; j < 8; j++) {\n crc = crc & 1 ? (crc >>> 1) ^ 0xedb88320 : crc >>> 1;\n }\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nexport function generateTokenLogo(name: string, symbol: string): Buffer {\n const seed = hashString(`${name}:${symbol}`);\n const rand = mulberry32(seed);\n\n // Pick gradient colors\n const hue1 = Math.floor(rand() * 360);\n const hue2 = (hue1 + 90 + Math.floor(rand() * 90)) % 360;\n const color1 = hslToRgb(hue1, 0.65, 0.5);\n const color2 = hslToRgb(hue2, 0.55, 0.35);\n\n // Pattern overlay color\n const patternColor = hslToRgb(hue1, 0.4, 0.9);\n\n const pattern = generatePattern(rand);\n\n // Render pixels\n const pixels = Buffer.alloc(SIZE * SIZE * 3);\n\n const gridSize = 7;\n const cellPx = 36;\n const gridWidth = gridSize * cellPx;\n const offsetX = Math.floor((SIZE - gridWidth) / 2);\n const offsetY = Math.floor((SIZE - gridWidth) / 2);\n const cornerRadius = 48;\n\n for (let y = 0; y < SIZE; y++) {\n for (let x = 0; x < SIZE; x++) {\n const idx = (y * SIZE + x) * 3;\n\n // Rounded corner mask — draw as square outside the radius\n const inCorner = isOutsideRoundedRect(x, y, SIZE, SIZE, cornerRadius);\n if (inCorner) {\n pixels[idx] = 0;\n pixels[idx + 1] = 0;\n pixels[idx + 2] = 0;\n continue;\n }\n\n // Diagonal gradient background\n const t = (x + y) / (SIZE * 2);\n let color = lerpColor(color1, color2, t);\n\n // Check if pixel is in the identicon pattern area\n const gx = x - offsetX;\n const gy = y - offsetY;\n if (gx >= 0 && gx < gridWidth && gy >= 0 && gy < gridWidth) {\n const col = Math.floor(gx / cellPx);\n const row = Math.floor(gy / cellPx);\n if (col < gridSize && row < gridSize && pattern[row][col]) {\n color = blendColor(color, patternColor, 0.35);\n }\n }\n\n pixels[idx] = color.r;\n pixels[idx + 1] = color.g;\n pixels[idx + 2] = color.b;\n }\n }\n\n return encodePng(SIZE, SIZE, pixels);\n}\n\nfunction isOutsideRoundedRect(\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n): boolean {\n // Only check corners\n if (x < r && y < r) {\n return (r - x) ** 2 + (r - y) ** 2 > r ** 2;\n }\n if (x >= w - r && y < r) {\n return (x - (w - r - 1)) ** 2 + (r - y) ** 2 > r ** 2;\n }\n if (x < r && y >= h - r) {\n return (r - x) ** 2 + (y - (h - r - 1)) ** 2 > r ** 2;\n }\n if (x >= w - r && y >= h - r) {\n return (x - (w - r - 1)) ** 2 + (y - (h - r - 1)) ** 2 > r ** 2;\n }\n return false;\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, MoltlaunchError } 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 try {\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 } 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 { loadLaunchRecords } from \"../lib/wallet.js\";\nimport { printError } from \"../lib/output.js\";\nimport { EXIT_CODES } from \"../lib/errors.js\";\n\ninterface StatusOpts {\n json: boolean;\n}\n\nexport async function status(opts: StatusOpts): Promise<void> {\n const { json } = opts;\n\n try {\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 } catch (error) {\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, getSigner, getWalletBalance } from \"../lib/wallet.js\";\nimport { REVENUE_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 FeeEscrow, claimed via the Revenue Manager\nconst REVENUE_MANAGER_ABI = [\n \"function balances(address) external view returns (uint256)\",\n \"function claim() external returns (uint256)\",\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 rm = new ethers.Contract(REVENUE_MANAGER_ADDRESS, REVENUE_MANAGER_ABI, signer);\n\n // Check claimable balance\n const claimable = await rm.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 claim transaction...\");\n\n // claim() pulls fees from FeeEscrow, deducts protocol fee, sends ETH to caller\n const tx = await rm.claim();\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 (!receipt) {\n throw new MoltlaunchError(\"Transaction was dropped or replaced\", EXIT_CODES.GENERAL);\n }\n if (!json) console.log(\" confirmed\");\n\n printSuccess(\"Fees claimed successfully!\", {\n transactionHash: receipt.hash,\n claimed: `${claimableEth} ETH (minus protocol fee)`,\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 { REVENUE_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 REVENUE_MANAGER_ABI = [\n \"function balances(address) external view returns (uint256)\",\n \"function protocolFee() 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 rm = new ethers.Contract(REVENUE_MANAGER_ADDRESS, REVENUE_MANAGER_ABI, provider);\n\n const claimable = await rm.balances(walletData.address);\n const claimableEth = ethers.formatEther(claimable);\n\n // Protocol takes a cut on claim (e.g. 1000 = 10%)\n let protocolFeeBps = 1000n;\n try { protocolFeeBps = await rm.protocolFee(); } catch { /* use default */ }\n const afterProtocol = claimable - (claimable * protocolFeeBps / 10000n);\n const afterProtocolEth = ethers.formatEther(afterProtocol);\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 afterProtocolFee: `~${afterProtocolEth} ETH`,\n protocolFee: `${Number(protocolFeeBps) / 100}%`,\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":";;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;;;ACDxB,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;AAKhC,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,MAAM,MAAM,IAAM,CAAC;AACjD,QAAM,MAAM,KAAK,GAAK;AAEtB,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;;;AEtGA,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,YACpB,QACiB;AACjB,MAAI;AACJ,MAAI;AAEJ,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,WAAW,MAAM,KAAK,MAAM;AAClC,QAAI,SAAS,OAAO,sBAAsB;AACxC,YAAM,IAAI,YAAY,6BAA6B,SAAS,OAAO,OAAO,MAAM,QAAQ,CAAC,CAAC,KAAK;AAAA,IACjG;AAEA,UAAM,cAAc,MAAMC,UAAS,MAAM;AACzC,aAAS,YAAY,SAAS,QAAQ;AAEtC,UAAM,MAAM,OAAO,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AACjD,UAAM,UAAkC;AAAA,MACtC,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM;AAAA,MACN,KAAK;AAAA,MACL,MAAM;AAAA,MACN,KAAK;AAAA,IACP;AACA,WAAO,QAAQ,OAAO,EAAE,KAAK;AAAA,EAC/B,OAAO;AACL,aAAS,OAAO,OAAO,SAAS,QAAQ;AACxC,WAAO,OAAO;AAAA,EAChB;AAEA,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,QAUjB;AAClB,QAAM,QAAQ,OAAO,YAAY,YAAY,MAAM,UAAU,MAAM;AAEnE,QAAM,OAA2C;AAAA,IAC/C,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO;AAAA,IACf,aAAa,OAAO;AAAA,IACpB,WAAW,OAAO;AAAA,IAClB,gBAAgB,OAAO;AAAA,IACvB,uBAAuB,OAAO;AAAA,IAC9B,YAAY,OAAO;AAAA,IACnB,YAAY,OAAO;AAAA,EACrB;AAGA,aAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,QAAI,KAAK,GAAG,MAAM,OAAW,QAAO,KAAK,GAAG;AAAA,EAC9C;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,MAAI,oBAAoB;AAExB,SAAO,KAAK,IAAI,IAAI,YAAY,iBAAiB;AAC/C,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,GAAG,gBAAgB,yBAAyB,KAAK,EAAE;AAAA,IAC5E,QAAQ;AAEN;AACA,UAAI,qBAAqB,GAAG;AAC1B,cAAM,IAAI,YAAY,kDAAkD;AAAA,MAC1E;AACA,YAAM,MAAM,gBAAgB;AAC5B;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,OAAO,SAAS,UAAU,KAAK;AACrD;AACA,UAAI,qBAAqB,GAAG;AAC1B,cAAM,IAAI,YAAY,sCAAsC,SAAS,MAAM,EAAE;AAAA,MAC/E;AACA,YAAM,MAAM,oBAAoB,oBAAoB,EAAE;AACtD;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,YAAY,wBAAwB,SAAS,MAAM,WAAM,IAAI,EAAE;AAAA,IAC3E;AAEA,wBAAoB;AACpB,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;;;AE7LA,SAAS,mBAAmB;AAE5B,IAAM,OAAO;AAEb,SAAS,WAAW,KAAqB;AACvC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAS,QAAQ,KAAK,OAAO,IAAI,WAAW,CAAC,IAAK;AAAA,EACpD;AACA,SAAO,KAAK,IAAI,IAAI;AACtB;AAEA,SAAS,WAAW,MAA4B;AAC9C,MAAI,IAAI,OAAO;AACf,SAAO,MAAM;AACX,QAAK,IAAI,aAAc;AACvB,QAAI,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;AACvC,QAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,KAAK,CAAC,IAAK;AAC7C,aAAS,IAAK,MAAM,QAAS,KAAK;AAAA,EACpC;AACF;AAQA,SAAS,SAAS,GAAW,GAAW,GAAgB;AACtD,QAAM,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;AAC/B,QAAM,IAAI,CAAC,MAAc;AACvB,UAAM,KAAK,IAAI,IAAI,MAAM;AACzB,WAAO,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE;AAAA,EACvD;AACA,SAAO;AAAA,IACL,GAAG,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;AAAA,IACxB,GAAG,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;AAAA,IACxB,GAAG,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;AAAA,EAC1B;AACF;AAEA,SAAS,UAAU,IAAS,IAAS,GAAgB;AACnD,SAAO;AAAA,IACL,GAAG,KAAK,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;AAAA,IACtC,GAAG,KAAK,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;AAAA,IACtC,GAAG,KAAK,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;AAAA,EACxC;AACF;AAEA,SAAS,WAAW,MAAW,SAAc,OAAoB;AAC/D,SAAO;AAAA,IACL,GAAG,KAAK,MAAM,KAAK,KAAK,IAAI,SAAS,QAAQ,IAAI,KAAK;AAAA,IACtD,GAAG,KAAK,MAAM,KAAK,KAAK,IAAI,SAAS,QAAQ,IAAI,KAAK;AAAA,IACtD,GAAG,KAAK,MAAM,KAAK,KAAK,IAAI,SAAS,QAAQ,IAAI,KAAK;AAAA,EACxD;AACF;AAGA,SAAS,gBAAgB,MAAiC;AACxD,QAAM,OAAoB,CAAC;AAC3B,WAAS,MAAM,GAAG,MAAM,GAAG,OAAO;AAChC,SAAK,GAAG,IAAI,CAAC;AACb,aAAS,MAAM,GAAG,MAAM,GAAG,OAAO;AAChC,WAAK,GAAG,EAAE,GAAG,IAAI,KAAK,IAAI;AAAA,IAC5B;AAEA,SAAK,GAAG,EAAE,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;AAC1B,SAAK,GAAG,EAAE,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;AAC1B,SAAK,GAAG,EAAE,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;AAAA,EAC5B;AACA,SAAO;AACT;AAGA,SAAS,UAAU,OAAe,QAAgB,QAAwB;AAExE,QAAM,UAAU,OAAO,MAAM,UAAU,IAAI,QAAQ,EAAE;AACrD,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,UAAM,YAAY,KAAK,IAAI,QAAQ;AACnC,YAAQ,SAAS,IAAI;AACrB,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,UAAU,IAAI,QAAQ,KAAK;AACjC,YAAM,SAAS,YAAY,IAAI,IAAI;AACnC,cAAQ,MAAM,IAAI,OAAO,MAAM;AAC/B,cAAQ,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC;AACvC,cAAQ,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC;AAAA,IACzC;AAAA,EACF;AAEA,QAAM,aAAa,YAAY,OAAO;AAGtC,QAAM,YAAY,OAAO,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;AAG/D,QAAM,WAAW,OAAO,MAAM,EAAE;AAChC,WAAS,cAAc,OAAO,CAAC;AAC/B,WAAS,cAAc,QAAQ,CAAC;AAChC,WAAS,CAAC,IAAI;AACd,WAAS,CAAC,IAAI;AACd,WAAS,EAAE,IAAI;AACf,WAAS,EAAE,IAAI;AACf,WAAS,EAAE,IAAI;AACf,QAAM,OAAO,UAAU,QAAQ,QAAQ;AAGvC,QAAM,OAAO,UAAU,QAAQ,UAAU;AAGzC,QAAM,OAAO,UAAU,QAAQ,OAAO,MAAM,CAAC,CAAC;AAE9C,SAAO,OAAO,OAAO,CAAC,WAAW,MAAM,MAAM,IAAI,CAAC;AACpD;AAEA,SAAS,UAAU,MAAc,MAAsB;AACrD,QAAM,SAAS,OAAO,MAAM,CAAC;AAC7B,SAAO,cAAc,KAAK,QAAQ,CAAC;AAEnC,QAAM,YAAY,OAAO,KAAK,MAAM,OAAO;AAC3C,QAAM,WAAW,OAAO,OAAO,CAAC,WAAW,IAAI,CAAC;AAChD,QAAM,MAAM,OAAO,MAAM,CAAC;AAC1B,MAAI,cAAc,MAAM,QAAQ,GAAG,CAAC;AAEpC,SAAO,OAAO,OAAO,CAAC,QAAQ,WAAW,MAAM,GAAG,CAAC;AACrD;AAEA,SAAS,MAAM,KAAqB;AAClC,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,WAAO,IAAI,CAAC;AACZ,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,MAAM,IAAK,QAAQ,IAAK,aAAa,QAAQ;AAAA,IACrD;AAAA,EACF;AACA,UAAQ,MAAM,gBAAgB;AAChC;AAEO,SAAS,kBAAkB,MAAc,QAAwB;AACtE,QAAM,OAAO,WAAW,GAAG,IAAI,IAAI,MAAM,EAAE;AAC3C,QAAM,OAAO,WAAW,IAAI;AAG5B,QAAM,OAAO,KAAK,MAAM,KAAK,IAAI,GAAG;AACpC,QAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE,KAAK;AACrD,QAAM,SAAS,SAAS,MAAM,MAAM,GAAG;AACvC,QAAM,SAAS,SAAS,MAAM,MAAM,IAAI;AAGxC,QAAM,eAAe,SAAS,MAAM,KAAK,GAAG;AAE5C,QAAM,UAAU,gBAAgB,IAAI;AAGpC,QAAM,SAAS,OAAO,MAAM,OAAO,OAAO,CAAC;AAE3C,QAAM,WAAW;AACjB,QAAM,SAAS;AACf,QAAM,YAAY,WAAW;AAC7B,QAAM,UAAU,KAAK,OAAO,OAAO,aAAa,CAAC;AACjD,QAAM,UAAU,KAAK,OAAO,OAAO,aAAa,CAAC;AACjD,QAAM,eAAe;AAErB,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,OAAO,IAAI,OAAO,KAAK;AAG7B,YAAM,WAAW,qBAAqB,GAAG,GAAG,MAAM,MAAM,YAAY;AACpE,UAAI,UAAU;AACZ,eAAO,GAAG,IAAI;AACd,eAAO,MAAM,CAAC,IAAI;AAClB,eAAO,MAAM,CAAC,IAAI;AAClB;AAAA,MACF;AAGA,YAAM,KAAK,IAAI,MAAM,OAAO;AAC5B,UAAI,QAAQ,UAAU,QAAQ,QAAQ,CAAC;AAGvC,YAAM,KAAK,IAAI;AACf,YAAM,KAAK,IAAI;AACf,UAAI,MAAM,KAAK,KAAK,aAAa,MAAM,KAAK,KAAK,WAAW;AAC1D,cAAM,MAAM,KAAK,MAAM,KAAK,MAAM;AAClC,cAAM,MAAM,KAAK,MAAM,KAAK,MAAM;AAClC,YAAI,MAAM,YAAY,MAAM,YAAY,QAAQ,GAAG,EAAE,GAAG,GAAG;AACzD,kBAAQ,WAAW,OAAO,cAAc,IAAI;AAAA,QAC9C;AAAA,MACF;AAEA,aAAO,GAAG,IAAI,MAAM;AACpB,aAAO,MAAM,CAAC,IAAI,MAAM;AACxB,aAAO,MAAM,CAAC,IAAI,MAAM;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO,UAAU,MAAM,MAAM,MAAM;AACrC;AAEA,SAAS,qBACP,GACA,GACA,GACA,GACA,GACS;AAET,MAAI,IAAI,KAAK,IAAI,GAAG;AAClB,YAAQ,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,KAAK;AAAA,EAC5C;AACA,MAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AACvB,YAAQ,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,MAAM,IAAI,KAAK;AAAA,EACtD;AACA,MAAI,IAAI,KAAK,KAAK,IAAI,GAAG;AACvB,YAAQ,IAAI,MAAM,KAAK,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK;AAAA,EACtD;AACA,MAAI,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG;AAC5B,YAAQ,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK;AAAA,EAChE;AACA,SAAO;AACT;;;AClOO,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;;;ANpBA,eAAsB,OAAO,MAAmC;AAC9D,QAAM,EAAE,MAAM,QAAQ,aAAa,SAAS,SAAS,SAAS,KAAK,IAAI;AACvE,QAAM,UAAmB,UAAU,YAAY;AAC/C,QAAM,QAAQ,UAAU,MAAM,UAAU,MAAM;AAE9C,MAAI;AAEF,QAAI;AAEJ,QAAI,KAAK,WAAW;AAClB,YAAM,gBAAgB,QAAQ,KAAK,SAAS;AAC5C,UAAI;AACF,cAAMC,QAAO,aAAa;AAAA,MAC5B,QAAQ;AACN,mBAAW,oBAAoB,aAAa,IAAI,MAAM,WAAW,WAAW;AAC5E,gBAAQ,KAAK,WAAW,WAAW;AAAA,MACrC;AACA,oBAAc;AAAA,IAChB,OAAO;AACL,UAAI,CAAC,KAAM,SAAQ,IAAI,2CAA2C;AAClE,oBAAc,EAAE,QAAQ,kBAAkB,MAAM,MAAM,GAAG,MAAM,YAAY;AAAA,IAC7E;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,WAAW;AAC/C,QAAI,CAAC,KAAM,SAAQ,IAAI,IAAI,UAAU,MAAM,GAAG,EAAE,CAAC,KAAK;AAGtD,QAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,sBAAsB;AAEtD,UAAM,aAAa,UACf,8BAA8B,OAAO,KACrC;AAEJ,UAAM,QAAQ,MAAM,eAAe;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgBA,QAAO;AAAA,MACvB,uBAAuB;AAAA,MACvB;AAAA,MACA,YAAY;AAAA,MACZ;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,QAAI,CAAC,OAAO,iBAAiB,WAAW,CAAC,OAAO,iBAAiB;AAC/D,YAAM,IAAI;AAAA,QACR;AAAA,QACA,WAAW;AAAA,MACb;AAAA,IACF;AAEA,UAAM,eAAe,OAAO,gBAAgB;AAC5C,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;;;AO5HA,eAAsB,OAAO,MAAiC;AAC5D,QAAM,EAAE,SAAS,KAAK,IAAI;AAE1B,MAAI;AACF,UAAM,OAAO,MAAM,WAAW;AAC9B,QAAI,CAAC,MAAM;AACT,iBAAW,oDAAoD,MAAM,WAAW,SAAS;AACzF,cAAQ,KAAK,WAAW,SAAS;AAAA,IACnC;AAEA,QAAI,UAAU;AACd,QAAI;AACF,gBAAU,MAAM,iBAAiB,KAAK,SAAS,SAAS;AAAA,IAC1D,QAAQ;AAAA,IAER;AAEA,UAAM,SAAkC;AAAA,MACtC,SAAS,KAAK;AAAA,MACd,SAAS,OAAO,UAAU,GAAG,OAAO;AAAA,MACpC,SAAS,OAAO,SAAS;AAAA,MACzB,WAAW,KAAK;AAAA,IAClB;AAEA,QAAI,SAAS;AACX,aAAO,aAAa,KAAK;AAAA,IAC3B;AAEA,iBAAa,eAAe,QAAQ,IAAI;AAAA,EAC1C,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;;;ACvCA,eAAsB,OAAO,MAAiC;AAC5D,QAAM,EAAE,KAAK,IAAI;AAEjB,MAAI;AACF,UAAM,UAAU,MAAM,kBAAkB;AAExC,QAAI,QAAQ,WAAW,GAAG;AACxB,UAAI,MAAM;AACR,gBAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC;AAAA,MAC7D,OAAO;AACL,gBAAQ,IAAI,6DAA6D;AAAA,MAC3E;AACA;AAAA,IACF;AAEA,QAAI,MAAM;AACR,cAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,UAAU,QAAQ,GAAG,MAAM,CAAC,CAAC;AACzE;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,mBAAsB,QAAQ,MAAM;AAAA,CAAM;AACtD,eAAW,UAAU,SAAS;AAC5B,cAAQ,IAAI,KAAK,OAAO,IAAI,KAAK,OAAO,MAAM,GAAG;AACjD,cAAQ,IAAI,iBAAiB,OAAO,YAAY,EAAE;AAClD,cAAQ,IAAI,iBAAiB,OAAO,eAAe,EAAE;AACrD,cAAQ,IAAI,iBAAiB,OAAO,UAAU,EAAE;AAChD,cAAQ,IAAI,iBAAiB,OAAO,OAAO,EAAE;AAC7C,cAAQ,IAAI,iBAAiB,OAAO,UAAU,EAAE;AAChD,cAAQ,IAAI;AAAA,IACd;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,eAAW,SAAS,MAAM,WAAW,OAAO;AAC5C,YAAQ,KAAK,WAAW,OAAO;AAAA,EACjC;AACF;;;AC3CA,SAAS,UAAAC,eAAc;AAQvB,IAAM,sBAAsB;AAAA,EAC1B;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,yBAAyB,qBAAqB,MAAM;AAGnF,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,iCAAiC;AAGjE,UAAM,KAAK,MAAM,GAAG,MAAM;AAC1B,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,SAAS;AACZ,YAAM,IAAI,gBAAgB,uCAAuC,WAAW,OAAO;AAAA,IACrF;AACA,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;;;AC/EA,SAAS,UAAAC,eAAc;AAOvB,IAAMC,uBAAsB;AAAA,EAC1B;AAAA,EACA;AACF;AAOA,eAAsB,KAAK,MAA+B;AACxD,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;AAEA,UAAM,QAAQ,UAAU,MAAM,UAAU,MAAM;AAC9C,UAAM,WAAW,IAAIC,QAAO,gBAAgB,MAAM,MAAM;AACxD,UAAM,KAAK,IAAIA,QAAO,SAAS,yBAAyBD,sBAAqB,QAAQ;AAErF,UAAM,YAAY,MAAM,GAAG,SAAS,WAAW,OAAO;AACtD,UAAM,eAAeC,QAAO,YAAY,SAAS;AAGjD,QAAI,iBAAiB;AACrB,QAAI;AAAE,uBAAiB,MAAM,GAAG,YAAY;AAAA,IAAG,QAAQ;AAAA,IAAoB;AAC3E,UAAM,gBAAgB,YAAa,YAAY,iBAAiB;AAChE,UAAM,mBAAmBA,QAAO,YAAY,aAAa;AAEzD,UAAM,gBAAgB,MAAM,iBAAiB,WAAW,SAAS,OAAO;AACxE,UAAM,SAAS,WAAW,aAAa,IAAI;AAE3C,iBAAa,eAAe;AAAA,MAC1B,WAAW,GAAG,YAAY;AAAA,MAC1B,kBAAkB,IAAI,gBAAgB;AAAA,MACtC,aAAa,GAAG,OAAO,cAAc,IAAI,GAAG;AAAA,MAC5C,QAAQ,WAAW;AAAA,MACnB,eAAe,GAAG,aAAa;AAAA,MAC/B;AAAA,MACA,SAAS,MAAM;AAAA,MACf,UAAU,UAAU,YAAY;AAAA,IAClC,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;;;AXtDA,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,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,OAAO,kBAAkB,6DAA6D,EACtF,OAAO,oBAAoB,qDAAqD,EAChF,OAAO,mBAAmB,mDAAmD,EAC7E,OAAO,aAAa,4BAA4B,KAAK,EACrD,OAAO,UAAU,+BAA+B,KAAK,EACrD;AAAA,EAAO,CAAC,SACP,OAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,QAAQ,KAAK;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK,SAAS;AAAA,IACzB,SAAS,KAAK;AAAA,IACd,SAAS,KAAK;AAAA,IACd,SAAS,KAAK;AAAA,IACd,MAAM,KAAK;AAAA,EACb,CAAC;AACH;AAEF,QACG,QAAQ,QAAQ,EAChB,YAAY,iCAAiC,EAC7C,OAAO,cAAc,oBAAoB,KAAK,EAC9C,OAAO,UAAU,kBAAkB,KAAK,EACxC;AAAA,EAAO,CAAC,SACP,OAAO,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AACnD;AAEF,QACG,QAAQ,QAAQ,EAChB,YAAY,sBAAsB,EAClC,OAAO,UAAU,kBAAkB,KAAK,EACxC;AAAA,EAAO,CAAC,SACP,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;AAC5B;AAEF,QACG,QAAQ,MAAM,EACd,YAAY,wDAAwD,EACpE,OAAO,aAAa,4BAA4B,KAAK,EACrD,OAAO,UAAU,kBAAkB,KAAK,EACxC;AAAA,EAAO,CAAC,SACP,KAAK,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AACjD;AAEF,QACG,QAAQ,OAAO,EACf,YAAY,uDAAuD,EACnE,OAAO,aAAa,4BAA4B,KAAK,EACrD,OAAO,UAAU,kBAAkB,KAAK,EACxC;AAAA,EAAO,CAAC,SACP,MAAM,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AAClD;AAEF,QAAQ,MAAM;","names":["access","wallet","readFile","resolve","readFile","access","wallet","ethers","ethers","ethers","REVENUE_MANAGER_ABI","ethers","require"]}
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/generate-logo.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 .option(\"--image <path>\", \"Path to token image (max 5MB, uses default logo if omitted)\")\n .option(\"--website <url>\", \"Website URL (overrides auto-created Moltbook post)\")\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 ?? undefined,\n website: opts.website,\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 { generateTokenLogo } from \"../lib/generate-logo.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, website, testnet, json } = opts;\n const network: Network = testnet ? \"testnet\" : \"mainnet\";\n const chain = testnet ? CHAIN.testnet : CHAIN.mainnet;\n\n try {\n // Resolve image: use provided path or generate a unique one\n let imageSource: string | { buffer: Buffer; mime: string };\n\n if (opts.imagePath) {\n const resolvedImage = resolve(opts.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 imageSource = resolvedImage;\n } else {\n if (!json) console.log(\"Generating unique logo from token name...\");\n imageSource = { buffer: generateTokenLogo(name, symbol), mime: \"image/png\" };\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(imageSource);\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\n const jobId = await launchMemecoin({\n name,\n symbol,\n description,\n imageIpfs,\n creatorAddress: wallet.address,\n revenueManagerAddress: REVENUE_MANAGER_ADDRESS,\n websiteUrl: website,\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 if (!result.collectionToken?.address || !result.transactionHash) {\n throw new MoltlaunchError(\n \"Launch completed but missing token address or transaction hash\",\n EXIT_CODES.LAUNCH_FAIL,\n );\n }\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, mode: 0o700 });\n await chmod(dir, 0o700);\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 * Accepts a file path or a {buffer, mime} object for generated images.\n */\nexport async function uploadImage(\n source: string | { buffer: Buffer; mime: string },\n): Promise<string> {\n let base64: string;\n let mime: string;\n\n if (typeof source === \"string\") {\n const fileStat = await stat(source);\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(source);\n base64 = imageBuffer.toString(\"base64\");\n\n const ext = source.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 mime = mimeMap[ext ?? \"\"] ?? \"image/png\";\n } else {\n base64 = source.buffer.toString(\"base64\");\n mime = source.mime;\n }\n\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 websiteUrl?: string;\n network: Network;\n}): Promise<string> {\n const chain = params.network === \"testnet\" ? CHAIN.testnet : CHAIN.mainnet;\n\n const body: Record<string, string | undefined> = {\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 websiteUrl: params.websiteUrl,\n };\n\n // Strip undefined values so we don't send nulls to the API\n for (const key of Object.keys(body)) {\n if (body[key] === undefined) delete body[key];\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 let consecutiveErrors = 0;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n let response: Response;\n try {\n response = await fetch(`${FLAUNCH_API_BASE}/api/v1/launch-status/${jobId}`);\n } catch {\n // Network error — retry up to 5 times before giving up\n consecutiveErrors++;\n if (consecutiveErrors >= 5) {\n throw new LaunchError(\"Lost connection to Flaunch API during deployment\");\n }\n await sleep(POLL_INTERVAL_MS);\n continue;\n }\n\n if (response.status === 429 || response.status >= 500) {\n consecutiveErrors++;\n if (consecutiveErrors >= 5) {\n throw new LaunchError(`Status check failed after retries: ${response.status}`);\n }\n await sleep(POLL_INTERVAL_MS * (consecutiveErrors + 1));\n continue;\n }\n\n if (!response.ok) {\n const text = await response.text();\n throw new LaunchError(`Status check failed: ${response.status} — ${text}`);\n }\n\n consecutiveErrors = 0;\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","/**\n * Generate a unique token logo PNG from the token name and symbol.\n * Zero external dependencies — produces a valid PNG using raw pixel data + zlib.\n * Deterministic: same inputs always produce the same image.\n */\n\nimport { deflateSync } from \"node:zlib\";\n\nconst SIZE = 512;\n\nfunction hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;\n }\n return Math.abs(hash);\n}\n\nfunction mulberry32(seed: number): () => number {\n let s = seed | 0;\n return () => {\n s = (s + 0x6d2b79f5) | 0;\n let t = Math.imul(s ^ (s >>> 15), 1 | s);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\ninterface RGB {\n r: number;\n g: number;\n b: number;\n}\n\nfunction hslToRgb(h: number, s: number, l: number): RGB {\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n };\n return {\n r: Math.round(255 * f(0)),\n g: Math.round(255 * f(8)),\n b: Math.round(255 * f(4)),\n };\n}\n\nfunction lerpColor(c1: RGB, c2: RGB, t: number): RGB {\n return {\n r: Math.round(c1.r + (c2.r - c1.r) * t),\n g: Math.round(c1.g + (c2.g - c1.g) * t),\n b: Math.round(c1.b + (c2.b - c1.b) * t),\n };\n}\n\nfunction blendColor(base: RGB, overlay: RGB, alpha: number): RGB {\n return {\n r: Math.round(base.r * (1 - alpha) + overlay.r * alpha),\n g: Math.round(base.g * (1 - alpha) + overlay.g * alpha),\n b: Math.round(base.b * (1 - alpha) + overlay.b * alpha),\n };\n}\n\n/** Generate a 7x7 vertically symmetric pattern */\nfunction generatePattern(rand: () => number): boolean[][] {\n const grid: boolean[][] = [];\n for (let row = 0; row < 7; row++) {\n grid[row] = [];\n for (let col = 0; col < 4; col++) {\n grid[row][col] = rand() > 0.5;\n }\n // Mirror horizontally\n grid[row][4] = grid[row][2];\n grid[row][5] = grid[row][1];\n grid[row][6] = grid[row][0];\n }\n return grid;\n}\n\n/** Encode raw RGBA pixels into a minimal PNG file */\nfunction encodePng(width: number, height: number, pixels: Buffer): Buffer {\n // Build raw image data with filter byte (0 = None) per row\n const rawData = Buffer.alloc(height * (1 + width * 3));\n for (let y = 0; y < height; y++) {\n const rowOffset = y * (1 + width * 3);\n rawData[rowOffset] = 0; // filter: None\n for (let x = 0; x < width; x++) {\n const srcIdx = (y * width + x) * 3;\n const dstIdx = rowOffset + 1 + x * 3;\n rawData[dstIdx] = pixels[srcIdx];\n rawData[dstIdx + 1] = pixels[srcIdx + 1];\n rawData[dstIdx + 2] = pixels[srcIdx + 2];\n }\n }\n\n const compressed = deflateSync(rawData);\n\n // PNG signature\n const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);\n\n // IHDR chunk\n const ihdrData = Buffer.alloc(13);\n ihdrData.writeUInt32BE(width, 0);\n ihdrData.writeUInt32BE(height, 4);\n ihdrData[8] = 8; // bit depth\n ihdrData[9] = 2; // color type: RGB\n ihdrData[10] = 0; // compression\n ihdrData[11] = 0; // filter\n ihdrData[12] = 0; // interlace\n const ihdr = makeChunk(\"IHDR\", ihdrData);\n\n // IDAT chunk\n const idat = makeChunk(\"IDAT\", compressed);\n\n // IEND chunk\n const iend = makeChunk(\"IEND\", Buffer.alloc(0));\n\n return Buffer.concat([signature, ihdr, idat, iend]);\n}\n\nfunction makeChunk(type: string, data: Buffer): Buffer {\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length, 0);\n\n const typeBytes = Buffer.from(type, \"ascii\");\n const crcInput = Buffer.concat([typeBytes, data]);\n const crc = Buffer.alloc(4);\n crc.writeUInt32BE(crc32(crcInput), 0);\n\n return Buffer.concat([length, typeBytes, data, crc]);\n}\n\nfunction crc32(buf: Buffer): number {\n let crc = 0xffffffff;\n for (let i = 0; i < buf.length; i++) {\n crc ^= buf[i];\n for (let j = 0; j < 8; j++) {\n crc = crc & 1 ? (crc >>> 1) ^ 0xedb88320 : crc >>> 1;\n }\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nexport function generateTokenLogo(name: string, symbol: string): Buffer {\n const seed = hashString(`${name}:${symbol}`);\n const rand = mulberry32(seed);\n\n // Pick gradient colors\n const hue1 = Math.floor(rand() * 360);\n const hue2 = (hue1 + 90 + Math.floor(rand() * 90)) % 360;\n const color1 = hslToRgb(hue1, 0.65, 0.5);\n const color2 = hslToRgb(hue2, 0.55, 0.35);\n\n // Pattern overlay color\n const patternColor = hslToRgb(hue1, 0.4, 0.9);\n\n const pattern = generatePattern(rand);\n\n // Render pixels\n const pixels = Buffer.alloc(SIZE * SIZE * 3);\n\n const gridSize = 7;\n const cellPx = 36;\n const gridWidth = gridSize * cellPx;\n const offsetX = Math.floor((SIZE - gridWidth) / 2);\n const offsetY = Math.floor((SIZE - gridWidth) / 2);\n const cornerRadius = 48;\n\n for (let y = 0; y < SIZE; y++) {\n for (let x = 0; x < SIZE; x++) {\n const idx = (y * SIZE + x) * 3;\n\n // Rounded corner mask — draw as square outside the radius\n const inCorner = isOutsideRoundedRect(x, y, SIZE, SIZE, cornerRadius);\n if (inCorner) {\n pixels[idx] = 0;\n pixels[idx + 1] = 0;\n pixels[idx + 2] = 0;\n continue;\n }\n\n // Diagonal gradient background\n const t = (x + y) / (SIZE * 2);\n let color = lerpColor(color1, color2, t);\n\n // Check if pixel is in the identicon pattern area\n const gx = x - offsetX;\n const gy = y - offsetY;\n if (gx >= 0 && gx < gridWidth && gy >= 0 && gy < gridWidth) {\n const col = Math.floor(gx / cellPx);\n const row = Math.floor(gy / cellPx);\n if (col < gridSize && row < gridSize && pattern[row][col]) {\n color = blendColor(color, patternColor, 0.35);\n }\n }\n\n pixels[idx] = color.r;\n pixels[idx + 1] = color.g;\n pixels[idx + 2] = color.b;\n }\n }\n\n return encodePng(SIZE, SIZE, pixels);\n}\n\nfunction isOutsideRoundedRect(\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n): boolean {\n // Only check corners\n if (x < r && y < r) {\n return (r - x) ** 2 + (r - y) ** 2 > r ** 2;\n }\n if (x >= w - r && y < r) {\n return (x - (w - r - 1)) ** 2 + (r - y) ** 2 > r ** 2;\n }\n if (x < r && y >= h - r) {\n return (r - x) ** 2 + (y - (h - r - 1)) ** 2 > r ** 2;\n }\n if (x >= w - r && y >= h - r) {\n return (x - (w - r - 1)) ** 2 + (y - (h - r - 1)) ** 2 > r ** 2;\n }\n return false;\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, MoltlaunchError } 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 try {\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 } 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 { loadLaunchRecords } from \"../lib/wallet.js\";\nimport { printError } from \"../lib/output.js\";\nimport { EXIT_CODES } from \"../lib/errors.js\";\n\ninterface StatusOpts {\n json: boolean;\n}\n\nexport async function status(opts: StatusOpts): Promise<void> {\n const { json } = opts;\n\n try {\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 } catch (error) {\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, getSigner, getWalletBalance } from \"../lib/wallet.js\";\nimport { REVENUE_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 FeeEscrow, claimed via the Revenue Manager\nconst REVENUE_MANAGER_ABI = [\n \"function balances(address) external view returns (uint256)\",\n \"function claim() external returns (uint256)\",\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 rm = new ethers.Contract(REVENUE_MANAGER_ADDRESS, REVENUE_MANAGER_ABI, signer);\n\n // Check claimable balance\n const claimable = await rm.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 claim transaction...\");\n\n // claim() pulls fees from FeeEscrow, deducts protocol fee, sends ETH to caller\n const tx = await rm.claim();\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 (!receipt) {\n throw new MoltlaunchError(\"Transaction was dropped or replaced\", EXIT_CODES.GENERAL);\n }\n if (!json) console.log(\" confirmed\");\n\n printSuccess(\"Fees claimed successfully!\", {\n transactionHash: receipt.hash,\n claimed: `${claimableEth} ETH (minus protocol fee)`,\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 { REVENUE_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 REVENUE_MANAGER_ABI = [\n \"function balances(address) external view returns (uint256)\",\n \"function protocolFee() 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 rm = new ethers.Contract(REVENUE_MANAGER_ADDRESS, REVENUE_MANAGER_ABI, provider);\n\n const claimable = await rm.balances(walletData.address);\n const claimableEth = ethers.formatEther(claimable);\n\n // Protocol takes a cut on claim (e.g. 1000 = 10%)\n let protocolFeeBps = 1000n;\n try { protocolFeeBps = await rm.protocolFee(); } catch { /* use default */ }\n const afterProtocol = claimable - (claimable * protocolFeeBps / 10000n);\n const afterProtocolEth = ethers.formatEther(afterProtocol);\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 afterProtocolFee: `~${afterProtocolEth} ETH`,\n protocolFee: `${Number(protocolFeeBps) / 100}%`,\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","REVENUE_MANAGER_ABI","ethers","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moltlaunch",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "CLI for AI agents to launch tokens on Base via Flaunch",
5
5
  "repository": {
6
6
  "type": "git",