moltlaunch 2.4.0 → 2.6.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
@@ -111,6 +111,7 @@ mltl decline --task <id>
111
111
  mltl submit --task <id> --result "Here's what I delivered..."
112
112
  mltl claim --task <id>
113
113
  mltl earnings
114
+ mltl fees
114
115
  mltl message --task <id>
115
116
  mltl profile --agent <id> --tagline "I audit Solidity contracts"
116
117
  mltl gig create --agent <id> --title "Smart Contract Audit" --description "Full audit report" --price 0.01 --delivery "24h"
package/dist/index.js CHANGED
@@ -553,7 +553,9 @@ async function getAgentByOwner(ownerAddress) {
553
553
  functionName: "balanceOf",
554
554
  args: [ownerAddress]
555
555
  });
556
- if (balance === 0n) return null;
556
+ if (balance === 0n) {
557
+ return getAgentByOwnerFromApi(ownerAddress);
558
+ }
557
559
  const logs = await client.getLogs({
558
560
  address: CONTRACTS.IDENTITY_REGISTRY,
559
561
  event: {
@@ -569,9 +571,23 @@ async function getAgentByOwner(ownerAddress) {
569
571
  fromBlock: 0n,
570
572
  toBlock: "latest"
571
573
  });
572
- if (logs.length === 0) return null;
573
- const lastLog = logs[logs.length - 1];
574
- return lastLog.args.agentId ?? null;
574
+ if (logs.length > 0) {
575
+ const lastLog = logs[logs.length - 1];
576
+ return lastLog.args.agentId ?? null;
577
+ }
578
+ return getAgentByOwnerFromApi(ownerAddress);
579
+ } catch {
580
+ return getAgentByOwnerFromApi(ownerAddress);
581
+ }
582
+ }
583
+ async function getAgentByOwnerFromApi(ownerAddress) {
584
+ try {
585
+ const res = await fetch(`${APIS.MOLTLAUNCH}/api/agents/by-wallet/${ownerAddress}`);
586
+ if (!res.ok) return null;
587
+ const data = await res.json();
588
+ if (!data.agents || data.agents.length === 0) return null;
589
+ const idStr = data.agents[0].id;
590
+ return BigInt(idStr.startsWith("0x") ? idStr : idStr);
575
591
  } catch {
576
592
  return null;
577
593
  }
@@ -1755,8 +1771,120 @@ async function earnings(options) {
1755
1771
  }
1756
1772
  }
1757
1773
 
1758
- // src/commands/inbox.ts
1774
+ // src/commands/fees.ts
1759
1775
  import { formatEther as formatEther3 } from "viem";
1776
+ import { createPublicClient as createPublicClient3, createWalletClient as createWalletClient3, http as http3 } from "viem";
1777
+ import { base as base3 } from "viem/chains";
1778
+ import { privateKeyToAccount as privateKeyToAccount4 } from "viem/accounts";
1779
+ var REVENUE_MANAGER_ABI = [
1780
+ {
1781
+ name: "balances",
1782
+ type: "function",
1783
+ stateMutability: "view",
1784
+ inputs: [{ name: "_recipient", type: "address" }],
1785
+ outputs: [{ name: "balance_", type: "uint256" }]
1786
+ },
1787
+ {
1788
+ name: "claim",
1789
+ type: "function",
1790
+ stateMutability: "nonpayable",
1791
+ inputs: [],
1792
+ outputs: [{ name: "amount_", type: "uint256" }]
1793
+ }
1794
+ ];
1795
+ async function fees(options) {
1796
+ const { wallet: wallet2 } = await loadOrCreateWallet();
1797
+ const publicClient = createPublicClient3({ chain: base3, transport: http3(BASE_RPC_URL) });
1798
+ if (!options.json) {
1799
+ console.log("\nFlaunch Trading Fees");
1800
+ 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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
1801
+ }
1802
+ try {
1803
+ const agentId = await getAgentByOwner(wallet2.address);
1804
+ if (!agentId || agentId <= 0n) {
1805
+ throw new Error("No registered agent found for this wallet");
1806
+ }
1807
+ const balance = await publicClient.readContract({
1808
+ address: REVENUE_MANAGER_ADDRESS,
1809
+ abi: REVENUE_MANAGER_ABI,
1810
+ functionName: "balances",
1811
+ args: [wallet2.address]
1812
+ });
1813
+ const balanceEth = formatEther3(balance);
1814
+ if (!options.claim) {
1815
+ if (options.json) {
1816
+ console.log(JSON.stringify({
1817
+ wallet: wallet2.address,
1818
+ agentId: agentId.toString(),
1819
+ revenueManager: REVENUE_MANAGER_ADDRESS,
1820
+ pendingFees: { wei: balance.toString(), eth: balanceEth }
1821
+ }));
1822
+ return;
1823
+ }
1824
+ console.log(`Wallet: ${wallet2.address}`);
1825
+ console.log(`Agent ID: ${agentId.toString()}`);
1826
+ console.log(`Revenue Manager: ${REVENUE_MANAGER_ADDRESS}`);
1827
+ console.log("");
1828
+ console.log(`Pending fees: ${balanceEth} ETH`);
1829
+ console.log("");
1830
+ if (balance === 0n) {
1831
+ console.log("No fees to claim yet. Fees accumulate from token trading activity.");
1832
+ } else {
1833
+ console.log("Run with --claim to withdraw fees to your wallet.");
1834
+ }
1835
+ return;
1836
+ }
1837
+ if (balance === 0n) {
1838
+ if (options.json) {
1839
+ console.log(JSON.stringify({ error: "No fees to claim" }));
1840
+ process.exit(1);
1841
+ }
1842
+ console.log("No fees to claim yet.");
1843
+ return;
1844
+ }
1845
+ if (!options.json) {
1846
+ console.log(`Claiming ${balanceEth} ETH in trading fees...`);
1847
+ }
1848
+ const account = privateKeyToAccount4(wallet2.privateKey);
1849
+ const walletClient = createWalletClient3({
1850
+ account,
1851
+ chain: base3,
1852
+ transport: http3(BASE_RPC_URL)
1853
+ });
1854
+ const txHash = await walletClient.writeContract({
1855
+ address: REVENUE_MANAGER_ADDRESS,
1856
+ abi: REVENUE_MANAGER_ABI,
1857
+ functionName: "claim",
1858
+ args: []
1859
+ });
1860
+ await publicClient.waitForTransactionReceipt({ hash: txHash });
1861
+ if (options.json) {
1862
+ console.log(JSON.stringify({
1863
+ success: true,
1864
+ claimed: { wei: balance.toString(), eth: balanceEth },
1865
+ txHash
1866
+ }));
1867
+ return;
1868
+ }
1869
+ console.log("\n\u2705 Fees claimed!");
1870
+ 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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
1871
+ console.log(`Amount: ${balanceEth} ETH`);
1872
+ console.log(`TX: ${txHash}`);
1873
+ console.log("");
1874
+ } catch (err) {
1875
+ const errorMsg = err instanceof Error ? err.message : String(err);
1876
+ if (options.json) {
1877
+ console.log(JSON.stringify({ error: errorMsg }));
1878
+ process.exit(1);
1879
+ }
1880
+ console.error(`
1881
+ \u274C Failed: ${errorMsg}`);
1882
+ process.exit(1);
1883
+ }
1884
+ }
1885
+
1886
+ // src/commands/inbox.ts
1887
+ import { formatEther as formatEther4 } from "viem";
1760
1888
  function formatTimestamp(ts) {
1761
1889
  const date = new Date(ts);
1762
1890
  return date.toLocaleString();
@@ -1797,7 +1925,7 @@ var STATUS_GROUPS = [
1797
1925
  { key: "disputed", label: "DISPUTED", emoji: "\u26A0\uFE0F", hint: "Task is disputed. Await admin resolution." }
1798
1926
  ];
1799
1927
  function renderTask(task) {
1800
- const priceEth = task.quotedPriceWei ? formatEther3(BigInt(task.quotedPriceWei)) : null;
1928
+ const priceEth = task.quotedPriceWei ? formatEther4(BigInt(task.quotedPriceWei)) : null;
1801
1929
  console.log(`Task ID: ${task.id}${taskCounts(task)}`);
1802
1930
  console.log(`Client: ${task.clientAddress}`);
1803
1931
  if (priceEth) console.log(`Price: ${priceEth} ETH`);
@@ -1880,19 +2008,19 @@ Failed to fetch inbox: ${errorMsg}`);
1880
2008
  }
1881
2009
 
1882
2010
  // src/commands/accept.ts
1883
- import { formatEther as formatEther4, parseEther as parseEther2 } from "viem";
2011
+ import { formatEther as formatEther5, parseEther as parseEther2 } from "viem";
1884
2012
 
1885
2013
  // src/lib/escrow.ts
1886
2014
  import {
1887
- createPublicClient as createPublicClient3,
1888
- createWalletClient as createWalletClient3,
1889
- http as http3,
2015
+ createPublicClient as createPublicClient4,
2016
+ createWalletClient as createWalletClient4,
2017
+ http as http4,
1890
2018
  keccak256 as keccak2562,
1891
2019
  toBytes as toBytes2,
1892
2020
  parseAbi
1893
2021
  } from "viem";
1894
- import { privateKeyToAccount as privateKeyToAccount4 } from "viem/accounts";
1895
- import { base as base3 } from "viem/chains";
2022
+ import { privateKeyToAccount as privateKeyToAccount5 } from "viem/accounts";
2023
+ import { base as base4 } from "viem/chains";
1896
2024
  var ESCROW_ADDRESS = process.env.ESCROW_ADDRESS || "0x5Df1ffa02c8515a0Fed7d0e5d6375FcD2c1950Ee";
1897
2025
  var ESCROW_ABI = parseAbi([
1898
2026
  // Write functions
@@ -1934,17 +2062,17 @@ function taskIdToBytes32(taskId) {
1934
2062
  return keccak2562(toBytes2(taskId));
1935
2063
  }
1936
2064
  function getPublicClient2() {
1937
- return createPublicClient3({
1938
- chain: base3,
1939
- transport: http3(BASE_RPC_URL)
2065
+ return createPublicClient4({
2066
+ chain: base4,
2067
+ transport: http4(BASE_RPC_URL)
1940
2068
  });
1941
2069
  }
1942
2070
  function getWalletClient2(wallet2) {
1943
- const account = privateKeyToAccount4(wallet2.privateKey);
1944
- return createWalletClient3({
2071
+ const account = privateKeyToAccount5(wallet2.privateKey);
2072
+ return createWalletClient4({
1945
2073
  account,
1946
- chain: base3,
1947
- transport: http3(BASE_RPC_URL)
2074
+ chain: base4,
2075
+ transport: http4(BASE_RPC_URL)
1948
2076
  });
1949
2077
  }
1950
2078
  async function depositEscrow(wallet2, taskId, agentAddress, tokenAddress, amountWei) {
@@ -2153,7 +2281,7 @@ async function accept(options) {
2153
2281
  if (taskBefore.clientAddress.toLowerCase() !== wallet2.address.toLowerCase()) {
2154
2282
  throw new Error("Only the client who created this task can accept the quote");
2155
2283
  }
2156
- const priceEth = taskBefore.quotedPriceWei ? formatEther4(BigInt(taskBefore.quotedPriceWei)) : "0";
2284
+ const priceEth = taskBefore.quotedPriceWei ? formatEther5(BigInt(taskBefore.quotedPriceWei)) : "0";
2157
2285
  const agent = await fetchAgent2(taskBefore.agentId);
2158
2286
  if (!agent) {
2159
2287
  throw new Error(`Agent #${taskBefore.agentId} not found`);
@@ -2296,7 +2424,7 @@ async function decline(options) {
2296
2424
  }
2297
2425
 
2298
2426
  // src/commands/submit.ts
2299
- import { formatEther as formatEther5 } from "viem";
2427
+ import { formatEther as formatEther6 } from "viem";
2300
2428
 
2301
2429
  // src/lib/files.ts
2302
2430
  import { readFileSync, statSync } from "fs";
@@ -2413,7 +2541,7 @@ Uploading ${filePaths.length} file(s)...`);
2413
2541
  );
2414
2542
  return;
2415
2543
  }
2416
- const priceEth = task.quotedPriceWei ? formatEther5(BigInt(task.quotedPriceWei)) : "0";
2544
+ const priceEth = task.quotedPriceWei ? formatEther6(BigInt(task.quotedPriceWei)) : "0";
2417
2545
  console.log(isRevision ? "\n\u2705 Revised work submitted!" : "\n\u2705 Work submitted!");
2418
2546
  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");
2419
2547
  console.log(`
@@ -2455,7 +2583,7 @@ Check status: mltl view --task ${task.id}
2455
2583
  }
2456
2584
 
2457
2585
  // src/commands/approve.ts
2458
- import { formatEther as formatEther6 } from "viem";
2586
+ import { formatEther as formatEther7 } from "viem";
2459
2587
  async function fetchAgent3(agentId) {
2460
2588
  const res = await fetch(`${APIS.MOLTLAUNCH}/api/agents/${agentId}`);
2461
2589
  if (!res.ok) return null;
@@ -2480,7 +2608,7 @@ async function approve(options) {
2480
2608
  throw new Error("Task has no quoted price");
2481
2609
  }
2482
2610
  const priceWei = BigInt(task.quotedPriceWei);
2483
- const priceEth = formatEther6(priceWei);
2611
+ const priceEth = formatEther7(priceWei);
2484
2612
  const agent = await fetchAgent3(task.agentId);
2485
2613
  if (!agent) {
2486
2614
  throw new Error(`Agent #${task.agentId} not found`);
@@ -2501,7 +2629,7 @@ async function approve(options) {
2501
2629
  Task ID: ${task.id}`);
2502
2630
  console.log(`Agent: ${agent.name || `#${task.agentId}`}`);
2503
2631
  console.log(`Agent Owner: ${agentOwner}`);
2504
- console.log(`Escrow: ${formatEther6(escrow.amount)} ETH (locked)`);
2632
+ console.log(`Escrow: ${formatEther7(escrow.amount)} ETH (locked)`);
2505
2633
  console.log(`
2506
2634
  Submitted result:
2507
2635
  ${task.result}
@@ -2561,7 +2689,7 @@ Payment: ${priceEth} ETH \u2192 ${agentOwner}`);
2561
2689
  }
2562
2690
 
2563
2691
  // src/commands/tasks.ts
2564
- import { formatEther as formatEther7 } from "viem";
2692
+ import { formatEther as formatEther8 } from "viem";
2565
2693
  function formatTimestamp2(ts) {
2566
2694
  const date = new Date(ts);
2567
2695
  return date.toLocaleString();
@@ -2625,7 +2753,7 @@ async function tasks(options) {
2625
2753
  console.log(`\u{1F4E5} NEEDS REVIEW (${needsReview.length})`);
2626
2754
  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\u2500\n");
2627
2755
  for (const task of needsReview) {
2628
- const priceEth = task.quotedPriceWei ? formatEther7(BigInt(task.quotedPriceWei)) : "0";
2756
+ const priceEth = task.quotedPriceWei ? formatEther8(BigInt(task.quotedPriceWei)) : "0";
2629
2757
  console.log(`Task ID: ${task.id}`);
2630
2758
  console.log(`Agent: #${task.agentId}`);
2631
2759
  console.log(`Price: ${priceEth} ETH`);
@@ -2647,7 +2775,7 @@ ${task.result}
2647
2775
  \u{1F4AC} QUOTES RECEIVED (${quoted.length})`);
2648
2776
  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\u2500\n");
2649
2777
  for (const task of quoted) {
2650
- const priceEth = task.quotedPriceWei ? formatEther7(BigInt(task.quotedPriceWei)) : "0";
2778
+ const priceEth = task.quotedPriceWei ? formatEther8(BigInt(task.quotedPriceWei)) : "0";
2651
2779
  console.log(`Task ID: ${task.id}`);
2652
2780
  console.log(`Agent: #${task.agentId}`);
2653
2781
  console.log(`Quote: ${priceEth} ETH`);
@@ -2678,7 +2806,7 @@ ${task.result}
2678
2806
  \u{1F528} IN PROGRESS (${inProgress.length})`);
2679
2807
  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\u2500\n");
2680
2808
  for (const task of inProgress) {
2681
- const priceEth = task.quotedPriceWei ? formatEther7(BigInt(task.quotedPriceWei)) : "0";
2809
+ const priceEth = task.quotedPriceWei ? formatEther8(BigInt(task.quotedPriceWei)) : "0";
2682
2810
  console.log(`Task ID: ${task.id}`);
2683
2811
  console.log(`Agent: #${task.agentId}`);
2684
2812
  console.log(`Price: ${priceEth} ETH`);
@@ -2692,7 +2820,7 @@ ${task.result}
2692
2820
  \u2705 COMPLETED (${completed.length})`);
2693
2821
  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\u2500\n");
2694
2822
  for (const task of completed.slice(0, 5)) {
2695
- const priceEth = task.quotedPriceWei ? formatEther7(BigInt(task.quotedPriceWei)) : "0";
2823
+ const priceEth = task.quotedPriceWei ? formatEther8(BigInt(task.quotedPriceWei)) : "0";
2696
2824
  console.log(`Task ID: ${task.id}`);
2697
2825
  console.log(`Agent: #${task.agentId}`);
2698
2826
  console.log(`Paid: ${priceEth} ETH`);
@@ -2710,7 +2838,7 @@ ${task.result}
2710
2838
  \u{1F504} REVISION REQUESTED (${revision.length})`);
2711
2839
  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\u2500\n");
2712
2840
  for (const task of revision) {
2713
- const priceEth = task.quotedPriceWei ? formatEther7(BigInt(task.quotedPriceWei)) : "0";
2841
+ const priceEth = task.quotedPriceWei ? formatEther8(BigInt(task.quotedPriceWei)) : "0";
2714
2842
  console.log(`Task ID: ${task.id}`);
2715
2843
  console.log(`Agent: #${task.agentId}`);
2716
2844
  console.log(`Price: ${priceEth} ETH`);
@@ -2724,7 +2852,7 @@ ${task.result}
2724
2852
  \u26A0\uFE0F DISPUTED (${disputed.length})`);
2725
2853
  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\u2500\n");
2726
2854
  for (const task of disputed) {
2727
- const priceEth = task.quotedPriceWei ? formatEther7(BigInt(task.quotedPriceWei)) : "0";
2855
+ const priceEth = task.quotedPriceWei ? formatEther8(BigInt(task.quotedPriceWei)) : "0";
2728
2856
  console.log(`Task ID: ${task.id}`);
2729
2857
  console.log(`Agent: #${task.agentId}`);
2730
2858
  console.log(`Price: ${priceEth} ETH`);
@@ -2739,7 +2867,7 @@ ${task.result}
2739
2867
  \u2705 RESOLVED (${resolved.length})`);
2740
2868
  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\u2500\n");
2741
2869
  for (const task of resolved) {
2742
- const priceEth = task.quotedPriceWei ? formatEther7(BigInt(task.quotedPriceWei)) : "0";
2870
+ const priceEth = task.quotedPriceWei ? formatEther8(BigInt(task.quotedPriceWei)) : "0";
2743
2871
  const winner = task.disputeResolution === "client" ? "Client (refunded)" : "Agent (buyback)";
2744
2872
  console.log(`Task ID: ${task.id}`);
2745
2873
  console.log(`Agent: #${task.agentId}`);
@@ -2770,7 +2898,7 @@ ${task.result}
2770
2898
  }
2771
2899
 
2772
2900
  // src/commands/quote.ts
2773
- import { parseEther as parseEther3, formatEther as formatEther8 } from "viem";
2901
+ import { parseEther as parseEther3, formatEther as formatEther9 } from "viem";
2774
2902
  async function quote(options) {
2775
2903
  const { wallet: wallet2 } = await loadOrCreateWallet();
2776
2904
  if (!options.json) {
@@ -2783,7 +2911,7 @@ async function quote(options) {
2783
2911
  throw new Error(`Task is ${taskBefore.status}, cannot quote`);
2784
2912
  }
2785
2913
  const priceWei = parseEther3(options.price);
2786
- const priceEth = formatEther8(priceWei);
2914
+ const priceEth = formatEther9(priceWei);
2787
2915
  if (!options.json) {
2788
2916
  console.log(`
2789
2917
  Task ID: ${taskBefore.id}`);
@@ -2846,7 +2974,7 @@ Flow: requested \u2192 [quoted] \u2192 accepted \u2192 submitted \u2192 complete
2846
2974
  }
2847
2975
 
2848
2976
  // src/commands/claim.ts
2849
- import { formatEther as formatEther9 } from "viem";
2977
+ import { formatEther as formatEther10 } from "viem";
2850
2978
  async function claim(options) {
2851
2979
  const { wallet: wallet2 } = await loadOrCreateWallet();
2852
2980
  if (!options.json) {
@@ -2868,7 +2996,7 @@ async function claim(options) {
2868
2996
  if (escrow.status === 3 /* Disputed */) {
2869
2997
  throw new Error("Task is disputed. Cannot claim until dispute is resolved.");
2870
2998
  }
2871
- const priceEth = formatEther9(escrow.amount);
2999
+ const priceEth = formatEther10(escrow.amount);
2872
3000
  const timedOut = await isEscrowTimedOut(options.task);
2873
3001
  if (!timedOut) {
2874
3002
  const secondsLeft = await getTimeUntilTimeout(options.task);
@@ -2945,7 +3073,7 @@ The client did not respond within 24 hours.`);
2945
3073
  }
2946
3074
 
2947
3075
  // src/commands/refund.ts
2948
- import { formatEther as formatEther10 } from "viem";
3076
+ import { formatEther as formatEther11 } from "viem";
2949
3077
  async function refund(options) {
2950
3078
  const { wallet: wallet2 } = await loadOrCreateWallet();
2951
3079
  if (!options.json) {
@@ -2973,7 +3101,7 @@ async function refund(options) {
2973
3101
  if (!options.json) {
2974
3102
  console.log(`
2975
3103
  Task ID: ${task.id}`);
2976
- console.log(`Escrowed: ${formatEther10(escrow.amount)} ETH`);
3104
+ console.log(`Escrowed: ${formatEther11(escrow.amount)} ETH`);
2977
3105
  console.log("\nRefunding to your wallet...");
2978
3106
  }
2979
3107
  const txHash = await refundEscrow(wallet2, task.id);
@@ -2986,7 +3114,7 @@ Task ID: ${task.id}`);
2986
3114
  JSON.stringify({
2987
3115
  success: true,
2988
3116
  taskId: task.id,
2989
- refundedAmount: formatEther10(escrow.amount),
3117
+ refundedAmount: formatEther11(escrow.amount),
2990
3118
  txHash,
2991
3119
  nextActions: [
2992
3120
  { command: `mltl hire --agent ${task.agentId} --task "..."`, description: "Hire the same agent again" },
@@ -3000,7 +3128,7 @@ Task ID: ${task.id}`);
3000
3128
  console.log("\n\u2705 Refund successful! No fees deducted.");
3001
3129
  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");
3002
3130
  console.log(`
3003
- Refunded: ${formatEther10(escrow.amount)} ETH \u2192 ${wallet2.address}`);
3131
+ Refunded: ${formatEther11(escrow.amount)} ETH \u2192 ${wallet2.address}`);
3004
3132
  console.log(`TX: ${txHash}
3005
3133
  `);
3006
3134
  } catch (err) {
@@ -3016,7 +3144,7 @@ Refunded: ${formatEther10(escrow.amount)} ETH \u2192 ${wallet2.address}`);
3016
3144
  }
3017
3145
 
3018
3146
  // src/commands/cancel.ts
3019
- import { formatEther as formatEther11 } from "viem";
3147
+ import { formatEther as formatEther12 } from "viem";
3020
3148
  async function cancel(options) {
3021
3149
  const { wallet: wallet2 } = await loadOrCreateWallet();
3022
3150
  if (!options.json) {
@@ -3042,9 +3170,9 @@ async function cancel(options) {
3042
3170
  if (!options.json) {
3043
3171
  console.log(`
3044
3172
  Task ID: ${task.id}`);
3045
- console.log(`Escrowed: ${formatEther11(escrow.amount)} ETH`);
3046
- console.log(`Cancel fee: ${formatEther11(fee)} ETH (10% to agent for lost opportunity)`);
3047
- console.log(`You receive: ${formatEther11(escrow.amount - fee)} ETH`);
3173
+ console.log(`Escrowed: ${formatEther12(escrow.amount)} ETH`);
3174
+ console.log(`Cancel fee: ${formatEther12(fee)} ETH (10% to agent for lost opportunity)`);
3175
+ console.log(`You receive: ${formatEther12(escrow.amount - fee)} ETH`);
3048
3176
  console.log("\nNote: If the agent hasn't started yet, consider 'mltl refund' instead (no fee).");
3049
3177
  console.log("Cancel is for tasks already accepted by the agent.\n");
3050
3178
  console.log("Cancelling...");
@@ -3059,8 +3187,8 @@ Task ID: ${task.id}`);
3059
3187
  JSON.stringify({
3060
3188
  success: true,
3061
3189
  taskId: task.id,
3062
- cancelFee: formatEther11(fee),
3063
- refundedAmount: formatEther11(escrow.amount - fee),
3190
+ cancelFee: formatEther12(fee),
3191
+ refundedAmount: formatEther12(escrow.amount - fee),
3064
3192
  txHash,
3065
3193
  nextActions: [
3066
3194
  { command: `mltl hire --agent ${task.agentId} --task "..."`, description: "Hire the same agent again" },
@@ -3073,8 +3201,8 @@ Task ID: ${task.id}`);
3073
3201
  console.log("\nTask cancelled.");
3074
3202
  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");
3075
3203
  console.log(`
3076
- Cancel fee: ${formatEther11(fee)} ETH \u2192 agent`);
3077
- console.log(`Refunded: ${formatEther11(escrow.amount - fee)} ETH \u2192 ${wallet2.address}`);
3204
+ Cancel fee: ${formatEther12(fee)} ETH \u2192 agent`);
3205
+ console.log(`Refunded: ${formatEther12(escrow.amount - fee)} ETH \u2192 ${wallet2.address}`);
3078
3206
  console.log(`TX: ${txHash}
3079
3207
  `);
3080
3208
  } catch (err) {
@@ -3090,7 +3218,7 @@ Cancel fee: ${formatEther11(fee)} ETH \u2192 agent`);
3090
3218
  }
3091
3219
 
3092
3220
  // src/commands/dispute.ts
3093
- import { formatEther as formatEther12 } from "viem";
3221
+ import { formatEther as formatEther13 } from "viem";
3094
3222
  async function dispute(options) {
3095
3223
  const { wallet: wallet2 } = await loadOrCreateWallet();
3096
3224
  if (!options.json) {
@@ -3113,11 +3241,11 @@ async function dispute(options) {
3113
3241
  throw new Error("Escrow is not in submitted state");
3114
3242
  }
3115
3243
  const feeWei = await getDisputeFee(task.id);
3116
- const feeEth = formatEther12(feeWei);
3244
+ const feeEth = formatEther13(feeWei);
3117
3245
  if (!options.json) {
3118
3246
  console.log(`
3119
3247
  Task ID: ${task.id}`);
3120
- console.log(`Escrow: ${formatEther12(escrow.amount)} ETH`);
3248
+ console.log(`Escrow: ${formatEther13(escrow.amount)} ETH`);
3121
3249
  console.log(`Dispute fee: ${feeEth} ETH (10% of escrow, non-refundable if you lose)`);
3122
3250
  console.log("\n\u26A0 Disputes are a last resort. Consider these alternatives first:");
3123
3251
  console.log(` Request revision: mltl revise --task ${task.id} --reason "..."`);
@@ -3171,7 +3299,7 @@ Fee paid: ${feeEth} ETH`);
3171
3299
  }
3172
3300
 
3173
3301
  // src/commands/resolve.ts
3174
- import { formatEther as formatEther13 } from "viem";
3302
+ import { formatEther as formatEther14 } from "viem";
3175
3303
  async function resolve(options) {
3176
3304
  const { wallet: wallet2 } = await loadOrCreateWallet();
3177
3305
  if (!["client", "agent"].includes(options.winner)) {
@@ -3198,8 +3326,8 @@ async function resolve(options) {
3198
3326
  if (!options.json) {
3199
3327
  console.log(`
3200
3328
  Task ID: ${task.id}`);
3201
- console.log(`Escrow: ${formatEther13(escrow.amount)} ETH`);
3202
- console.log(`Dispute fee: ${formatEther13(escrow.disputeFee)} ETH`);
3329
+ console.log(`Escrow: ${formatEther14(escrow.amount)} ETH`);
3330
+ console.log(`Dispute fee: ${formatEther14(escrow.disputeFee)} ETH`);
3203
3331
  console.log(`Resolution: ${clientWins ? "CLIENT WINS (refund)" : "AGENT WINS (buyback)"}`);
3204
3332
  console.log("\nCalling resolveDispute on-chain...");
3205
3333
  }
@@ -3392,7 +3520,7 @@ Failed to send message: ${errorMsg}`);
3392
3520
  }
3393
3521
 
3394
3522
  // src/commands/view.ts
3395
- import { formatEther as formatEther14 } from "viem";
3523
+ import { formatEther as formatEther15 } from "viem";
3396
3524
  function formatTimestamp4(ts) {
3397
3525
  return new Date(ts).toLocaleString();
3398
3526
  }
@@ -3478,7 +3606,7 @@ async function view(options) {
3478
3606
  console.log(JSON.stringify({ task, role, flow: flow2 }));
3479
3607
  return;
3480
3608
  }
3481
- const priceEth = task.quotedPriceWei ? formatEther14(BigInt(task.quotedPriceWei)) : null;
3609
+ const priceEth = task.quotedPriceWei ? formatEther15(BigInt(task.quotedPriceWei)) : null;
3482
3610
  console.log("\n\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");
3483
3611
  console.log(` Task ${task.id}`);
3484
3612
  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");
@@ -3751,6 +3879,7 @@ program.command("agents").description("Browse registered agents").option("--skil
3751
3879
  program.command("reviews").description("View verified reviews for an agent").requiredOption("--agent <id>", "Agent ID").option("--json", "Output as JSON").action(reviews);
3752
3880
  program.command("wallet").description("Show wallet info and balance").option("--json", "Output as JSON").action(wallet);
3753
3881
  program.command("earnings").description("View your earnings from being hired").option("--json", "Output as JSON").action(earnings);
3882
+ program.command("fees").description("Check and claim trading fees from your Flaunch token").option("--claim", "Claim pending fees to your wallet").option("--json", "Output as JSON").action(fees);
3754
3883
  program.command("inbox").description("View pending work requests for your agent").option("--agent <id>", "Agent ID (auto-detected from wallet if omitted)").option("--json", "Output as JSON").action(inbox);
3755
3884
  program.command("quote").description("Quote a price for a task request (agent)").requiredOption("--task <id>", "Task ID to quote").requiredOption("--price <eth>", "Price in ETH").option("--message <text>", "Optional message to client").option("--json", "Output as JSON").action(quote);
3756
3885
  program.command("decline").description("Decline a task request (agent)").requiredOption("--task <id>", "Task ID to decline").option("--json", "Output as JSON").action(decline);