moltlaunch 2.10.0 → 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 +10 -2
- package/dist/index.js +41 -40
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
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
|
|
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
|
-
|
|
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
|
@@ -60,7 +60,9 @@ var METADATA_KEYS = {
|
|
|
60
60
|
|
|
61
61
|
// src/lib/builder-code.ts
|
|
62
62
|
import { encodeFunctionData } from "viem";
|
|
63
|
-
|
|
63
|
+
import { Attribution } from "ox/erc8021";
|
|
64
|
+
var DATA_SUFFIX = Attribution.toDataSuffix({ codes: [BUILDER_CODE_SUFFIX] });
|
|
65
|
+
var SUFFIX_HEX = DATA_SUFFIX.slice(2);
|
|
64
66
|
async function writeContractWithAttribution(walletClient, params) {
|
|
65
67
|
const calldata = encodeFunctionData({
|
|
66
68
|
abi: params.abi,
|
|
@@ -877,12 +879,12 @@ async function register(options) {
|
|
|
877
879
|
process.exit(1);
|
|
878
880
|
}
|
|
879
881
|
const hasExistingToken = options.token && /^0x[a-fA-F0-9]{40}$/.test(options.token);
|
|
880
|
-
if (
|
|
882
|
+
if (options.symbol && (options.symbol.length < 2 || options.symbol.length > 10)) {
|
|
881
883
|
if (options.json) {
|
|
882
|
-
console.log(JSON.stringify({ error: "
|
|
884
|
+
console.log(JSON.stringify({ error: "--symbol must be 2-10 characters" }));
|
|
883
885
|
process.exit(1);
|
|
884
886
|
}
|
|
885
|
-
console.error("\u274C
|
|
887
|
+
console.error("\u274C --symbol must be 2-10 characters");
|
|
886
888
|
process.exit(1);
|
|
887
889
|
}
|
|
888
890
|
const skills = options.skills.split(",").map((s) => s.trim().toLowerCase());
|
|
@@ -894,8 +896,10 @@ async function register(options) {
|
|
|
894
896
|
console.log(`Name: ${options.name}`);
|
|
895
897
|
if (hasExistingToken) {
|
|
896
898
|
console.log(`Token: ${options.token} (existing)`);
|
|
897
|
-
} else {
|
|
899
|
+
} else if (symbol) {
|
|
898
900
|
console.log(`Token: $${symbol} (new launch)`);
|
|
901
|
+
} else {
|
|
902
|
+
console.log(`Token: (none \u2014 direct ETH payment)`);
|
|
899
903
|
}
|
|
900
904
|
console.log(`Description: ${options.description}`);
|
|
901
905
|
console.log(`Skills: ${skills.join(", ")}`);
|
|
@@ -915,30 +919,14 @@ async function register(options) {
|
|
|
915
919
|
try {
|
|
916
920
|
if (hasExistingToken) {
|
|
917
921
|
if (!options.json) {
|
|
918
|
-
console.log("Step 1:
|
|
919
|
-
}
|
|
920
|
-
try {
|
|
921
|
-
const flaunchRes = await fetch(`${APIS.FLAUNCH_DATA}/v1/base/tokens/${options.token}`);
|
|
922
|
-
if (!flaunchRes.ok) {
|
|
923
|
-
const msg = "Token not found on Base. Only tokens launched via Flaunch are supported.";
|
|
924
|
-
if (options.json) {
|
|
925
|
-
console.log(JSON.stringify({ error: msg, token: options.token }));
|
|
926
|
-
} else {
|
|
927
|
-
console.error(`\u274C ${msg}`);
|
|
928
|
-
console.error(` Launch a new token with --symbol instead, or use a valid token address.`);
|
|
929
|
-
}
|
|
930
|
-
process.exit(1);
|
|
931
|
-
}
|
|
932
|
-
} catch {
|
|
922
|
+
console.log("Step 1: Using existing token...\n");
|
|
933
923
|
}
|
|
934
924
|
tokenAddress = options.token;
|
|
935
|
-
flaunchUrl = `https://flaunch.gg/base/coin/${options.token}`;
|
|
936
925
|
if (!options.json) {
|
|
937
|
-
console.log(` \u2713 Token: ${tokenAddress}
|
|
938
|
-
console.log(` \u2713 URL: ${flaunchUrl}
|
|
926
|
+
console.log(` \u2713 Token: ${tokenAddress}
|
|
939
927
|
`);
|
|
940
928
|
}
|
|
941
|
-
} else {
|
|
929
|
+
} else if (options.symbol) {
|
|
942
930
|
if (!options.json) {
|
|
943
931
|
console.log("Step 1: Launching token on Base...\n");
|
|
944
932
|
}
|
|
@@ -960,6 +948,10 @@ async function register(options) {
|
|
|
960
948
|
console.log(` \u2713 TX: ${tokenTxHash}
|
|
961
949
|
`);
|
|
962
950
|
}
|
|
951
|
+
} else {
|
|
952
|
+
if (!options.json) {
|
|
953
|
+
console.log("Step 1: Skipped (no token \u2014 direct ETH payment)\n");
|
|
954
|
+
}
|
|
963
955
|
}
|
|
964
956
|
if (!options.json) {
|
|
965
957
|
console.log("Step 2: Registering agent identity...\n");
|
|
@@ -974,7 +966,7 @@ async function register(options) {
|
|
|
974
966
|
skills,
|
|
975
967
|
endpoint: options.endpoint || "",
|
|
976
968
|
priceWei: parseEther(options.price),
|
|
977
|
-
flaunchToken: tokenAddress
|
|
969
|
+
flaunchToken: tokenAddress ? tokenAddress : void 0
|
|
978
970
|
});
|
|
979
971
|
let registrationStatus = "unknown";
|
|
980
972
|
try {
|
|
@@ -1033,8 +1025,12 @@ async function register(options) {
|
|
|
1033
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");
|
|
1034
1026
|
console.log(`Agent ID: ${agentResult.agentId}`);
|
|
1035
1027
|
console.log(`Name: ${options.name}`);
|
|
1036
|
-
|
|
1037
|
-
|
|
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
|
+
}
|
|
1038
1034
|
console.log(`Skills: ${skills.join(", ")}`);
|
|
1039
1035
|
if (options.endpoint) {
|
|
1040
1036
|
console.log(`Endpoint: ${options.endpoint}`);
|
|
@@ -1045,7 +1041,11 @@ async function register(options) {
|
|
|
1045
1041
|
console.log(`Wallet: ${wallet2.address}`);
|
|
1046
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");
|
|
1047
1043
|
console.log("\nLinks:");
|
|
1048
|
-
|
|
1044
|
+
if (flaunchUrl) {
|
|
1045
|
+
console.log(` Token: ${flaunchUrl}`);
|
|
1046
|
+
} else if (tokenAddress) {
|
|
1047
|
+
console.log(` Token: https://basescan.org/token/${tokenAddress}`);
|
|
1048
|
+
}
|
|
1049
1049
|
if (tokenTxHash) {
|
|
1050
1050
|
console.log(` Token TX: ${CHAIN.explorer}/tx/${tokenTxHash}`);
|
|
1051
1051
|
}
|
|
@@ -1060,8 +1060,10 @@ async function register(options) {
|
|
|
1060
1060
|
console.log("\nTo receive work requests, run:");
|
|
1061
1061
|
console.log(` mltl inbox --agent ${agentResult.agentId}`);
|
|
1062
1062
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1063
|
+
if (flaunchUrl) {
|
|
1064
|
+
console.log("\nOthers can invest in your agent at:");
|
|
1065
|
+
console.log(` ${flaunchUrl}`);
|
|
1066
|
+
}
|
|
1065
1067
|
if (registrationStatus === "pending") {
|
|
1066
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");
|
|
1067
1069
|
console.log("\n\u23F3 Your agent is pending admin approval.");
|
|
@@ -1807,8 +1809,9 @@ async function earnings(options) {
|
|
|
1807
1809
|
console.log(` Feedback received: ${feedbackCount}`);
|
|
1808
1810
|
console.log(` Average score: ${avgScore > 0 ? avgScore.toFixed(1) + "/100" : "N/A"}`);
|
|
1809
1811
|
console.log("");
|
|
1810
|
-
console.log("
|
|
1811
|
-
console.log("
|
|
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.");
|
|
1812
1815
|
} catch (err) {
|
|
1813
1816
|
if (options.json) {
|
|
1814
1817
|
console.log(
|
|
@@ -1952,7 +1955,7 @@ async function fees(options) {
|
|
|
1952
1955
|
console.log("");
|
|
1953
1956
|
if (tokens.length === 0) {
|
|
1954
1957
|
console.log("No tokens found for this wallet in the Revenue Manager.");
|
|
1955
|
-
console.log("
|
|
1958
|
+
console.log("Trading fees only apply to agents with a Flaunch token (registered with --symbol).");
|
|
1956
1959
|
} else if (balance === 0n) {
|
|
1957
1960
|
console.log("No fees to claim yet. Fees accumulate from token trading activity.");
|
|
1958
1961
|
} else {
|
|
@@ -1966,6 +1969,7 @@ async function fees(options) {
|
|
|
1966
1969
|
process.exit(1);
|
|
1967
1970
|
}
|
|
1968
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).");
|
|
1969
1973
|
return;
|
|
1970
1974
|
}
|
|
1971
1975
|
if (balance === 0n) {
|
|
@@ -2426,10 +2430,7 @@ async function accept(options) {
|
|
|
2426
2430
|
if (!agentOwner) {
|
|
2427
2431
|
throw new Error("Agent has no owner address");
|
|
2428
2432
|
}
|
|
2429
|
-
const agentToken = agent.flaunchToken;
|
|
2430
|
-
if (!agentToken) {
|
|
2431
|
-
throw new Error("Agent has no token linked. Cannot deposit to escrow without token for buyback.");
|
|
2432
|
-
}
|
|
2433
|
+
const agentToken = agent.flaunchToken || "0x0000000000000000000000000000000000000001";
|
|
2433
2434
|
const priceWei = BigInt(taskBefore.quotedPriceWei || "0");
|
|
2434
2435
|
const balance = await getWalletBalance(wallet2.address);
|
|
2435
2436
|
const balanceWei = parseEther2(balance);
|
|
@@ -2454,7 +2455,7 @@ ${taskBefore.task}
|
|
|
2454
2455
|
console.log(`
|
|
2455
2456
|
This will deposit ${priceEth} ETH into escrow.`);
|
|
2456
2457
|
console.log("Funds are locked until you approve the work or request a refund.");
|
|
2457
|
-
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");
|
|
2458
2459
|
console.log(" - Cancel before submission: 10% fee to agent, 90% refunded");
|
|
2459
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");
|
|
2460
2461
|
console.log("\nDepositing funds into escrow...");
|
|
@@ -2494,7 +2495,7 @@ This will deposit ${priceEth} ETH into escrow.`);
|
|
|
2494
2495
|
console.log("\n\u2705 Quote accepted! Funds locked in escrow.");
|
|
2495
2496
|
console.log(`
|
|
2496
2497
|
Escrow: ${priceEth} ETH deposited`);
|
|
2497
|
-
console.log(`Token: ${
|
|
2498
|
+
console.log(`Token: ${agent.flaunchToken || "(none \u2014 direct ETH payment)"}`);
|
|
2498
2499
|
console.log(`TX: ${escrowTxHash}`);
|
|
2499
2500
|
console.log("\nThe agent can now begin work. When they submit:");
|
|
2500
2501
|
console.log(" - Review & approve: mltl approve --task " + task.id);
|
|
@@ -4077,7 +4078,7 @@ async function verifyX(options) {
|
|
|
4077
4078
|
// src/index.ts
|
|
4078
4079
|
var program = new Command();
|
|
4079
4080
|
program.name("mltl").description("moltlaunch \u2014 hire AI agents with onchain reputation").version("2.8.0");
|
|
4080
|
-
program.command("register").description("Register an agent (
|
|
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);
|
|
4081
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);
|
|
4082
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);
|
|
4083
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);
|