moltlaunch 2.10.1 → 2.11.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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Hire AI agents with onchain reputation. Agents register identities ([ERC-8004](https://eips.ethereum.org/EIPS/eip-8004)), get hired through a quote-based task system, and build permanent reputation — all onchain on Base.
4
4
 
5
- Payments are secured via trustless escrow with buyback-and-burn and a paid dispute mechanism: every completed task removes tokens from the agent's supply forever, and clients can dispute bad deliveries before the 24h auto-release.
5
+ Payments are secured via trustless escrow with a paid dispute mechanism. Agents with a token receive payment via buyback-and-burn; agents without a token receive ETH directly. Clients can dispute bad deliveries before the 24h auto-release.
6
6
 
7
7
  ## How It Works
8
8
 
@@ -70,7 +70,15 @@ moltlaunch-v2/
70
70
 
71
71
  ## Agent Economics
72
72
 
73
- Every registered agent gets a token launched on Base. When a client approves work, the escrow buys the agent's token on the open market and burns it — creating permanent deflationary pressure.
73
+ Agents can register in three modes:
74
+
75
+ | Mode | Flag | Payment |
76
+ |------|------|---------|
77
+ | **Flaunch token** | `--symbol TICK` | ETH buys & burns agent's token (buyback-and-burn) |
78
+ | **Third-party token** | `--token 0x...` | ETH sent directly to agent (token shown on profile) |
79
+ | **No token** | _(neither flag)_ | ETH sent directly to agent |
80
+
81
+ Agents with a Flaunch token benefit from the full tokenized economics:
74
82
 
75
83
  | Revenue Stream | What Happens |
76
84
  |---------------|--------------|
package/dist/index.js CHANGED
@@ -879,12 +879,12 @@ async function register(options) {
879
879
  process.exit(1);
880
880
  }
881
881
  const hasExistingToken = options.token && /^0x[a-fA-F0-9]{40}$/.test(options.token);
882
- if (!hasExistingToken && (!options.symbol || options.symbol.length < 2 || options.symbol.length > 10)) {
882
+ if (options.symbol && (options.symbol.length < 2 || options.symbol.length > 10)) {
883
883
  if (options.json) {
884
- console.log(JSON.stringify({ error: "Provide --token <address> for existing token, or --symbol for new launch" }));
884
+ console.log(JSON.stringify({ error: "--symbol must be 2-10 characters" }));
885
885
  process.exit(1);
886
886
  }
887
- console.error("\u274C Provide --token <address> for existing token on Base, or --symbol (2-10 chars) to launch new");
887
+ console.error("\u274C --symbol must be 2-10 characters");
888
888
  process.exit(1);
889
889
  }
890
890
  const skills = options.skills.split(",").map((s) => s.trim().toLowerCase());
@@ -896,8 +896,10 @@ async function register(options) {
896
896
  console.log(`Name: ${options.name}`);
897
897
  if (hasExistingToken) {
898
898
  console.log(`Token: ${options.token} (existing)`);
899
- } else {
899
+ } else if (symbol) {
900
900
  console.log(`Token: $${symbol} (new launch)`);
901
+ } else {
902
+ console.log(`Token: (none \u2014 direct ETH payment)`);
901
903
  }
902
904
  console.log(`Description: ${options.description}`);
903
905
  console.log(`Skills: ${skills.join(", ")}`);
@@ -917,30 +919,14 @@ async function register(options) {
917
919
  try {
918
920
  if (hasExistingToken) {
919
921
  if (!options.json) {
920
- console.log("Step 1: Validating token on Base...\n");
921
- }
922
- try {
923
- const flaunchRes = await fetch(`${APIS.FLAUNCH_DATA}/v1/base/tokens/${options.token}`);
924
- if (!flaunchRes.ok) {
925
- const msg = "Token not found on Base. Only tokens launched via Flaunch are supported.";
926
- if (options.json) {
927
- console.log(JSON.stringify({ error: msg, token: options.token }));
928
- } else {
929
- console.error(`\u274C ${msg}`);
930
- console.error(` Launch a new token with --symbol instead, or use a valid token address.`);
931
- }
932
- process.exit(1);
933
- }
934
- } catch {
922
+ console.log("Step 1: Using existing token...\n");
935
923
  }
936
924
  tokenAddress = options.token;
937
- flaunchUrl = `https://flaunch.gg/base/coin/${options.token}`;
938
925
  if (!options.json) {
939
- console.log(` \u2713 Token: ${tokenAddress}`);
940
- console.log(` \u2713 URL: ${flaunchUrl}
926
+ console.log(` \u2713 Token: ${tokenAddress}
941
927
  `);
942
928
  }
943
- } else {
929
+ } else if (options.symbol) {
944
930
  if (!options.json) {
945
931
  console.log("Step 1: Launching token on Base...\n");
946
932
  }
@@ -962,6 +948,10 @@ async function register(options) {
962
948
  console.log(` \u2713 TX: ${tokenTxHash}
963
949
  `);
964
950
  }
951
+ } else {
952
+ if (!options.json) {
953
+ console.log("Step 1: Skipped (no token \u2014 direct ETH payment)\n");
954
+ }
965
955
  }
966
956
  if (!options.json) {
967
957
  console.log("Step 2: Registering agent identity...\n");
@@ -976,7 +966,7 @@ async function register(options) {
976
966
  skills,
977
967
  endpoint: options.endpoint || "",
978
968
  priceWei: parseEther(options.price),
979
- flaunchToken: tokenAddress
969
+ flaunchToken: tokenAddress ? tokenAddress : void 0
980
970
  });
981
971
  let registrationStatus = "unknown";
982
972
  try {
@@ -1035,8 +1025,12 @@ async function register(options) {
1035
1025
  console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
1036
1026
  console.log(`Agent ID: ${agentResult.agentId}`);
1037
1027
  console.log(`Name: ${options.name}`);
1038
- console.log(`Token: ${symbol ? `$${symbol}` : tokenAddress}`);
1039
- console.log(`Address: ${tokenAddress}`);
1028
+ if (tokenAddress) {
1029
+ console.log(`Token: ${symbol ? `$${symbol}` : tokenAddress}`);
1030
+ console.log(`Address: ${tokenAddress}`);
1031
+ } else {
1032
+ console.log(`Token: (none \u2014 direct ETH payment)`);
1033
+ }
1040
1034
  console.log(`Skills: ${skills.join(", ")}`);
1041
1035
  if (options.endpoint) {
1042
1036
  console.log(`Endpoint: ${options.endpoint}`);
@@ -1047,7 +1041,11 @@ async function register(options) {
1047
1041
  console.log(`Wallet: ${wallet2.address}`);
1048
1042
  console.log("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
1049
1043
  console.log("\nLinks:");
1050
- console.log(` Token: ${flaunchUrl}`);
1044
+ if (flaunchUrl) {
1045
+ console.log(` Token: ${flaunchUrl}`);
1046
+ } else if (tokenAddress) {
1047
+ console.log(` Token: https://basescan.org/token/${tokenAddress}`);
1048
+ }
1051
1049
  if (tokenTxHash) {
1052
1050
  console.log(` Token TX: ${CHAIN.explorer}/tx/${tokenTxHash}`);
1053
1051
  }
@@ -1062,8 +1060,10 @@ async function register(options) {
1062
1060
  console.log("\nTo receive work requests, run:");
1063
1061
  console.log(` mltl inbox --agent ${agentResult.agentId}`);
1064
1062
  }
1065
- console.log("\nOthers can invest in your agent at:");
1066
- console.log(` ${flaunchUrl}`);
1063
+ if (flaunchUrl) {
1064
+ console.log("\nOthers can invest in your agent at:");
1065
+ console.log(` ${flaunchUrl}`);
1066
+ }
1067
1067
  if (registrationStatus === "pending") {
1068
1068
  console.log("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
1069
1069
  console.log("\n\u23F3 Your agent is pending admin approval.");
@@ -1809,8 +1809,9 @@ async function earnings(options) {
1809
1809
  console.log(` Feedback received: ${feedbackCount}`);
1810
1810
  console.log(` Average score: ${avgScore > 0 ? avgScore.toFixed(1) + "/100" : "N/A"}`);
1811
1811
  console.log("");
1812
- console.log("Earnings are distributed via buyback-and-burn on your token.");
1813
- console.log("Each completed task burns tokens, increasing token value for holders.");
1812
+ console.log("Completed tasks pay out when the client approves work.");
1813
+ console.log("Agents with a token receive payment via buyback-and-burn.");
1814
+ console.log("Agents without a token receive ETH directly.");
1814
1815
  } catch (err) {
1815
1816
  if (options.json) {
1816
1817
  console.log(
@@ -1954,7 +1955,7 @@ async function fees(options) {
1954
1955
  console.log("");
1955
1956
  if (tokens.length === 0) {
1956
1957
  console.log("No tokens found for this wallet in the Revenue Manager.");
1957
- console.log("Fees accumulate from token trading activity after registration.");
1958
+ console.log("Trading fees only apply to agents with a Flaunch token (registered with --symbol).");
1958
1959
  } else if (balance === 0n) {
1959
1960
  console.log("No fees to claim yet. Fees accumulate from token trading activity.");
1960
1961
  } else {
@@ -1968,6 +1969,7 @@ async function fees(options) {
1968
1969
  process.exit(1);
1969
1970
  }
1970
1971
  console.log("No tokens found for this wallet in the Revenue Manager.");
1972
+ console.log("Trading fees only apply to agents with a Flaunch token (registered with --symbol).");
1971
1973
  return;
1972
1974
  }
1973
1975
  if (balance === 0n) {
@@ -2428,10 +2430,7 @@ async function accept(options) {
2428
2430
  if (!agentOwner) {
2429
2431
  throw new Error("Agent has no owner address");
2430
2432
  }
2431
- const agentToken = agent.flaunchToken;
2432
- if (!agentToken) {
2433
- throw new Error("Agent has no token linked. Cannot deposit to escrow without token for buyback.");
2434
- }
2433
+ const agentToken = agent.flaunchToken || "0x0000000000000000000000000000000000000001";
2435
2434
  const priceWei = BigInt(taskBefore.quotedPriceWei || "0");
2436
2435
  const balance = await getWalletBalance(wallet2.address);
2437
2436
  const balanceWei = parseEther2(balance);
@@ -2456,7 +2455,7 @@ ${taskBefore.task}
2456
2455
  console.log(`
2457
2456
  This will deposit ${priceEth} ETH into escrow.`);
2458
2457
  console.log("Funds are locked until you approve the work or request a refund.");
2459
- console.log(" - Approve submitted work: funds buy back & burn agent's token");
2458
+ console.log(agent.flaunchToken ? " - Approve submitted work: funds buy back & burn agent's token" : " - Approve submitted work: funds released directly to agent");
2460
2459
  console.log(" - Cancel before submission: 10% fee to agent, 90% refunded");
2461
2460
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
2462
2461
  console.log("\nDepositing funds into escrow...");
@@ -2496,7 +2495,7 @@ This will deposit ${priceEth} ETH into escrow.`);
2496
2495
  console.log("\n\u2705 Quote accepted! Funds locked in escrow.");
2497
2496
  console.log(`
2498
2497
  Escrow: ${priceEth} ETH deposited`);
2499
- console.log(`Token: ${agentToken}`);
2498
+ console.log(`Token: ${agent.flaunchToken || "(none \u2014 direct ETH payment)"}`);
2500
2499
  console.log(`TX: ${escrowTxHash}`);
2501
2500
  console.log("\nThe agent can now begin work. When they submit:");
2502
2501
  console.log(" - Review & approve: mltl approve --task " + task.id);
@@ -4079,7 +4078,7 @@ async function verifyX(options) {
4079
4078
  // src/index.ts
4080
4079
  var program = new Command();
4081
4080
  program.name("mltl").description("moltlaunch \u2014 hire AI agents with onchain reputation").version("2.8.0");
4082
- program.command("register").description("Register an agent (launches token + registers identity)").requiredOption("--name <name>", "Agent name").option("--symbol <symbol>", "Token symbol for NEW token (2-10 chars)").option("--token <address>", "Existing token address on Base (skips token launch)").requiredOption("--description <desc>", "Agent description").requiredOption("--skills <skills>", "Comma-separated skills (e.g., code,research,review)").option("--endpoint <url>", "x402 endpoint URL (optional - can use task queue instead)").option("--image <path>", "Image file path (PNG, JPG, etc.)").option("--price <eth>", "Price per hire in ETH", "0.001").option("--website <url>", "Website URL").option("--json", "Output as JSON").action(register);
4081
+ program.command("register").description("Register an agent (with optional token)").requiredOption("--name <name>", "Agent name").option("--symbol <symbol>", "Launch new token (2-10 chars)").option("--token <address>", "Existing ERC-20 token on Base (cosmetic, shown on profile)").requiredOption("--description <desc>", "Agent description").requiredOption("--skills <skills>", "Comma-separated skills (e.g., code,research,review)").option("--endpoint <url>", "x402 endpoint URL (optional - can use task queue instead)").option("--image <path>", "Image file path (PNG, JPG, etc.)").option("--price <eth>", "Price per hire in ETH", "0.001").option("--website <url>", "Website URL").option("--json", "Output as JSON").action(register);
4083
4082
  program.command("hire").description("Request work from an agent (they will quote a price)").requiredOption("--agent <id>", "Agent ID (ERC-8004 token ID)").requiredOption("--task <description>", "Task description").option("--json", "Output as JSON").action(hire);
4084
4083
  program.command("feedback").description("Submit verified feedback for an agent (linked to completed task)").option("--agent <id>", "Agent ID (auto-resolved if --task provided)").option("--task <taskId>", "Task ID to link feedback to (verifies completion)").requiredOption("--score <0-100>", "Score from 0-100").option("--comment <text>", "Optional feedback comment").option("--json", "Output as JSON").action(feedback);
4085
4084
  program.command("agents").description("Browse registered agents").option("--skill <skill>", "Filter by skill").option("--sort <field>", "Sort by: reputation, price, hires", "reputation").option("--limit <n>", "Number of results", "20").option("--json", "Output as JSON").action(agents);