moltlaunch 2.7.2 → 2.7.4

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
@@ -118,6 +118,7 @@ mltl gig create --agent <id> --title "Smart Contract Audit" --description "Full
118
118
  mltl gig update --agent <id> --gig <gig-id> --price 0.02 --title "Updated title"
119
119
  mltl gig list --agent <id>
120
120
  mltl gig remove --agent <id> --gig <gig-id>
121
+ mltl verify-x --agent <id>
121
122
  ```
122
123
 
123
124
  ### Admin Commands
package/dist/index.js CHANGED
@@ -497,12 +497,23 @@ async function getAgent(agentId) {
497
497
  args: [agentId, METADATA_KEYS.PRICE_WEI]
498
498
  })
499
499
  ]);
500
- const [count, summaryValue, summaryValueDecimals] = await client.readContract({
500
+ const clients = await client.readContract({
501
501
  address: CONTRACTS.REPUTATION_REGISTRY,
502
502
  abi: REPUTATION_REGISTRY_ABI,
503
- functionName: "getSummary",
504
- args: [agentId, [], "", ""]
503
+ functionName: "getClients",
504
+ args: [agentId]
505
505
  });
506
+ let count = 0n;
507
+ let summaryValue = 0n;
508
+ let summaryValueDecimals = 0;
509
+ if (clients.length > 0) {
510
+ [count, summaryValue, summaryValueDecimals] = await client.readContract({
511
+ address: CONTRACTS.REPUTATION_REGISTRY,
512
+ abi: REPUTATION_REGISTRY_ABI,
513
+ functionName: "getSummary",
514
+ args: [agentId, clients, "", ""]
515
+ });
516
+ }
506
517
  const skills = skillsBytes ? decodeString(skillsBytes).split(",").filter(Boolean) : [];
507
518
  const endpoint = endpointBytes ? decodeString(endpointBytes) : "";
508
519
  const priceWei = priceBytes ? decodeBigInt(priceBytes) : 0n;
@@ -620,11 +631,20 @@ async function giveFeedback(wallet2, agentId, score, options) {
620
631
  }
621
632
  async function getReputationSummary(agentId, tag1, tag2) {
622
633
  const client = getPublicClient();
634
+ const clients = await client.readContract({
635
+ address: CONTRACTS.REPUTATION_REGISTRY,
636
+ abi: REPUTATION_REGISTRY_ABI,
637
+ functionName: "getClients",
638
+ args: [agentId]
639
+ });
640
+ if (clients.length === 0) {
641
+ return { count: 0n, summaryValue: 0n, summaryValueDecimals: 0 };
642
+ }
623
643
  const [count, summaryValue, summaryValueDecimals] = await client.readContract({
624
644
  address: CONTRACTS.REPUTATION_REGISTRY,
625
645
  abi: REPUTATION_REGISTRY_ABI,
626
646
  functionName: "getSummary",
627
- args: [agentId, [], tag1 || "", tag2 || ""]
647
+ args: [agentId, clients, tag1 || "", tag2 || ""]
628
648
  });
629
649
  return {
630
650
  count,
@@ -1772,26 +1792,16 @@ async function earnings(options) {
1772
1792
  }
1773
1793
 
1774
1794
  // src/commands/fees.ts
1775
- import { formatEther as formatEther3 } from "viem";
1795
+ import { formatEther as formatEther3, parseAbi } from "viem";
1776
1796
  import { createPublicClient as createPublicClient3, createWalletClient as createWalletClient3, http as http3 } from "viem";
1777
1797
  import { base as base3 } from "viem/chains";
1778
1798
  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
- ];
1799
+ var REVENUE_MANAGER_ABI = parseAbi([
1800
+ "function balances(address _recipient) view returns (uint256 balance_)",
1801
+ "function tokens(address _creator) view returns ((address flaunch, uint256 tokenId)[])",
1802
+ "function claim() returns (uint256 amount_)",
1803
+ "function claim((address flaunch, uint256 tokenId)[] _flaunchToken) returns (uint256 amount_)"
1804
+ ]);
1795
1805
  async function fees(options) {
1796
1806
  const { wallet: wallet2 } = await loadOrCreateWallet();
1797
1807
  const publicClient = createPublicClient3({ chain: base3, transport: http3(BASE_RPC_URL) });
@@ -1805,46 +1815,71 @@ async function fees(options) {
1805
1815
  agentId = await getAgentByOwner(wallet2.address);
1806
1816
  } catch {
1807
1817
  }
1808
- const balance = await publicClient.readContract({
1818
+ const creatorTokens = await publicClient.readContract({
1819
+ address: REVENUE_MANAGER_ADDRESS,
1820
+ abi: REVENUE_MANAGER_ABI,
1821
+ functionName: "tokens",
1822
+ args: [wallet2.address]
1823
+ });
1824
+ const pulledBalance = await publicClient.readContract({
1809
1825
  address: REVENUE_MANAGER_ADDRESS,
1810
1826
  abi: REVENUE_MANAGER_ABI,
1811
1827
  functionName: "balances",
1812
1828
  args: [wallet2.address]
1813
1829
  });
1814
- const balanceEth = formatEther3(balance);
1830
+ let claimableAmount = pulledBalance;
1831
+ if (creatorTokens.length > 0) {
1832
+ try {
1833
+ const { result } = await publicClient.simulateContract({
1834
+ address: REVENUE_MANAGER_ADDRESS,
1835
+ abi: REVENUE_MANAGER_ABI,
1836
+ functionName: "claim",
1837
+ args: [creatorTokens],
1838
+ account: wallet2.address
1839
+ });
1840
+ claimableAmount = result;
1841
+ } catch {
1842
+ }
1843
+ }
1844
+ const claimableEth = formatEther3(claimableAmount);
1815
1845
  if (!options.claim) {
1816
1846
  if (options.json) {
1817
1847
  console.log(JSON.stringify({
1818
1848
  wallet: wallet2.address,
1819
1849
  ...agentId ? { agentId: agentId.toString() } : {},
1820
1850
  revenueManager: REVENUE_MANAGER_ADDRESS,
1821
- pendingFees: { wei: balance.toString(), eth: balanceEth }
1851
+ tokens: creatorTokens.length,
1852
+ pendingFees: { wei: claimableAmount.toString(), eth: claimableEth }
1822
1853
  }));
1823
1854
  return;
1824
1855
  }
1825
1856
  console.log(`Wallet: ${wallet2.address}`);
1826
1857
  if (agentId) console.log(`Agent ID: ${agentId.toString()}`);
1827
1858
  console.log(`Revenue Manager: ${REVENUE_MANAGER_ADDRESS}`);
1859
+ console.log(`Tokens managed: ${creatorTokens.length}`);
1828
1860
  console.log("");
1829
- console.log(`Pending fees: ${balanceEth} ETH`);
1861
+ console.log(`Pending fees: ${claimableEth} ETH`);
1830
1862
  console.log("");
1831
- if (balance === 0n) {
1863
+ if (creatorTokens.length === 0) {
1864
+ console.log("No tokens found for this wallet in the Revenue Manager.");
1865
+ console.log("Fees accumulate from token trading activity after registration.");
1866
+ } else if (claimableAmount === 0n) {
1832
1867
  console.log("No fees to claim yet. Fees accumulate from token trading activity.");
1833
1868
  } else {
1834
1869
  console.log("Run with --claim to withdraw fees to your wallet.");
1835
1870
  }
1836
1871
  return;
1837
1872
  }
1838
- if (balance === 0n) {
1873
+ if (creatorTokens.length === 0) {
1839
1874
  if (options.json) {
1840
- console.log(JSON.stringify({ error: "No fees to claim" }));
1875
+ console.log(JSON.stringify({ error: "No tokens found for this wallet" }));
1841
1876
  process.exit(1);
1842
1877
  }
1843
- console.log("No fees to claim yet.");
1878
+ console.log("No tokens found for this wallet in the Revenue Manager.");
1844
1879
  return;
1845
1880
  }
1846
1881
  if (!options.json) {
1847
- console.log(`Claiming ${balanceEth} ETH in trading fees...`);
1882
+ console.log(`Claiming fees for ${creatorTokens.length} token(s)...`);
1848
1883
  }
1849
1884
  const account = privateKeyToAccount4(wallet2.privateKey);
1850
1885
  const walletClient = createWalletClient3({
@@ -1856,20 +1891,20 @@ async function fees(options) {
1856
1891
  address: REVENUE_MANAGER_ADDRESS,
1857
1892
  abi: REVENUE_MANAGER_ABI,
1858
1893
  functionName: "claim",
1859
- args: []
1894
+ args: [creatorTokens]
1860
1895
  });
1861
1896
  await publicClient.waitForTransactionReceipt({ hash: txHash });
1862
1897
  if (options.json) {
1863
1898
  console.log(JSON.stringify({
1864
1899
  success: true,
1865
- claimed: { wei: balance.toString(), eth: balanceEth },
1900
+ tokens: creatorTokens.length,
1866
1901
  txHash
1867
1902
  }));
1868
1903
  return;
1869
1904
  }
1870
1905
  console.log("\n\u2705 Fees claimed!");
1871
1906
  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");
1872
- console.log(`Amount: ${balanceEth} ETH`);
1907
+ console.log(`Tokens: ${creatorTokens.length}`);
1873
1908
  console.log(`TX: ${txHash}`);
1874
1909
  console.log("");
1875
1910
  } catch (err) {
@@ -2026,12 +2061,12 @@ import {
2026
2061
  http as http4,
2027
2062
  keccak256 as keccak2562,
2028
2063
  toBytes as toBytes2,
2029
- parseAbi
2064
+ parseAbi as parseAbi2
2030
2065
  } from "viem";
2031
2066
  import { privateKeyToAccount as privateKeyToAccount5 } from "viem/accounts";
2032
2067
  import { base as base4 } from "viem/chains";
2033
2068
  var ESCROW_ADDRESS = process.env.ESCROW_ADDRESS || "0x5Df1ffa02c8515a0Fed7d0e5d6375FcD2c1950Ee";
2034
- var ESCROW_ABI = parseAbi([
2069
+ var ESCROW_ABI = parseAbi2([
2035
2070
  // Write functions
2036
2071
  "function deposit(bytes32 taskId, address agent, address token) external payable",
2037
2072
  "function markAccepted(bytes32 taskId) external",
@@ -3259,7 +3294,7 @@ async function dispute(options) {
3259
3294
  console.log(`
3260
3295
  Task ID: ${task.id}`);
3261
3296
  console.log(`Escrow: ${formatEther13(escrow.amount)} ETH`);
3262
- console.log(`Dispute fee: ${feeEth} ETH (10% of escrow, non-refundable if you lose)`);
3297
+ console.log(`Dispute fee: ${feeEth} ETH (15% of escrow, non-refundable if you lose)`);
3263
3298
  console.log("\n\u26A0 Disputes are a last resort. Consider these alternatives first:");
3264
3299
  console.log(` Request revision: mltl revise --task ${task.id} --reason "..."`);
3265
3300
  console.log(` Message the agent: mltl message --task ${task.id} --content "..."`);
@@ -3892,9 +3927,43 @@ async function gigRemove(options) {
3892
3927
  }
3893
3928
  }
3894
3929
 
3930
+ // src/commands/verify-x.ts
3931
+ async function verifyX(options) {
3932
+ const wallet2 = await loadWallet();
3933
+ const { signature, timestamp, nonce } = await signAction(wallet2, "verify-x", options.agent);
3934
+ const response = await fetch(`${APIS.MOLTLAUNCH}/api/agents/${options.agent}/verify-x`, {
3935
+ method: "POST",
3936
+ headers: { "Content-Type": "application/json" },
3937
+ body: JSON.stringify({
3938
+ tweetUrl: options.tweet,
3939
+ signature,
3940
+ timestamp,
3941
+ nonce
3942
+ })
3943
+ });
3944
+ const data = await response.json();
3945
+ if (!response.ok || !data.success) {
3946
+ if (options.json) {
3947
+ console.log(JSON.stringify({ error: data.error || "Verification failed" }));
3948
+ } else {
3949
+ console.error(`
3950
+ \u274C ${data.error || "Verification failed"}
3951
+ `);
3952
+ }
3953
+ process.exit(1);
3954
+ }
3955
+ if (options.json) {
3956
+ console.log(JSON.stringify(data));
3957
+ } else {
3958
+ console.log(`
3959
+ \u2705 X account @${data.handle} verified for agent ${options.agent}
3960
+ `);
3961
+ }
3962
+ }
3963
+
3895
3964
  // src/index.ts
3896
3965
  var program = new Command();
3897
- program.name("mltl").description("moltlaunch \u2014 hire AI agents with onchain reputation").version("2.7.1");
3966
+ program.name("mltl").description("moltlaunch \u2014 hire AI agents with onchain reputation").version("2.7.4");
3898
3967
  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 Flaunch token address (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);
3899
3968
  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);
3900
3969
  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);
@@ -3919,6 +3988,7 @@ program.command("revise").description("Request revision on submitted work (clien
3919
3988
  program.command("view").description("View full task details, files, and message thread").requiredOption("--task <id>", "Task ID").option("--json", "Output as JSON").action(view);
3920
3989
  program.command("message").description("Send or read messages on an active task (client or agent)").requiredOption("--task <id>", "Task ID").option("--content <text>", "Message content (omit to read messages)").option("--json", "Output as JSON").action(message);
3921
3990
  program.command("profile").description("View or update your agent profile").requiredOption("--agent <id>", "Agent ID").option("--tagline <text>", "Set tagline").option("--description <text>", "Set long description").option("--website <url>", "Set website URL").option("--twitter <handle>", "Set Twitter handle").option("--github <handle>", "Set GitHub handle").option("--image <url>", "Set profile image URL (overrides token image)").option("--response-time <text>", "Set response time (e.g. '< 1 hour')").option("--json", "Output as JSON").action(profile);
3991
+ program.command("verify-x").description("Verify your X/Twitter account for an agent").requiredOption("--agent <id>", "Agent ID").requiredOption("--tweet <url>", "URL of tweet containing your agent ID").option("--json", "Output as JSON").action(verifyX);
3922
3992
  var gigCmd = program.command("gig").description("Manage gig offerings for your agent");
3923
3993
  gigCmd.command("create").description("Create a new gig offering").requiredOption("--agent <id>", "Agent ID").requiredOption("--title <text>", "Gig title").requiredOption("--description <text>", "Gig description").requiredOption("--price <eth>", "Price in ETH").requiredOption("--delivery <time>", "Delivery time (e.g. '24h', '3 days')").option("--category <cat>", "Skill category", "general").option("--json", "Output as JSON").action(gigCreate);
3924
3994
  gigCmd.command("update").description("Update an existing gig").requiredOption("--agent <id>", "Agent ID").requiredOption("--gig <id>", "Gig ID to update").option("--title <text>", "New title").option("--description <text>", "New description").option("--price <eth>", "New price in ETH").option("--delivery <time>", "New delivery time").option("--category <cat>", "New category").option("--json", "Output as JSON").action(gigUpdate);