moltlaunch 2.10.1 → 2.12.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 +42 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -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
|
@@ -99,6 +99,10 @@ function getWalletDir() {
|
|
|
99
99
|
return join(homedir(), WALLET_DIR);
|
|
100
100
|
}
|
|
101
101
|
function getWalletPath() {
|
|
102
|
+
const profile2 = process.env.MLTL_WALLET;
|
|
103
|
+
if (profile2) {
|
|
104
|
+
return join(getWalletDir(), `wallet-${profile2}.json`);
|
|
105
|
+
}
|
|
102
106
|
return join(getWalletDir(), WALLET_FILE);
|
|
103
107
|
}
|
|
104
108
|
async function fileExists(path) {
|
|
@@ -879,12 +883,12 @@ async function register(options) {
|
|
|
879
883
|
process.exit(1);
|
|
880
884
|
}
|
|
881
885
|
const hasExistingToken = options.token && /^0x[a-fA-F0-9]{40}$/.test(options.token);
|
|
882
|
-
if (
|
|
886
|
+
if (options.symbol && (options.symbol.length < 2 || options.symbol.length > 10)) {
|
|
883
887
|
if (options.json) {
|
|
884
|
-
console.log(JSON.stringify({ error: "
|
|
888
|
+
console.log(JSON.stringify({ error: "--symbol must be 2-10 characters" }));
|
|
885
889
|
process.exit(1);
|
|
886
890
|
}
|
|
887
|
-
console.error("\u274C
|
|
891
|
+
console.error("\u274C --symbol must be 2-10 characters");
|
|
888
892
|
process.exit(1);
|
|
889
893
|
}
|
|
890
894
|
const skills = options.skills.split(",").map((s) => s.trim().toLowerCase());
|
|
@@ -896,8 +900,10 @@ async function register(options) {
|
|
|
896
900
|
console.log(`Name: ${options.name}`);
|
|
897
901
|
if (hasExistingToken) {
|
|
898
902
|
console.log(`Token: ${options.token} (existing)`);
|
|
899
|
-
} else {
|
|
903
|
+
} else if (symbol) {
|
|
900
904
|
console.log(`Token: $${symbol} (new launch)`);
|
|
905
|
+
} else {
|
|
906
|
+
console.log(`Token: (none \u2014 direct ETH payment)`);
|
|
901
907
|
}
|
|
902
908
|
console.log(`Description: ${options.description}`);
|
|
903
909
|
console.log(`Skills: ${skills.join(", ")}`);
|
|
@@ -917,30 +923,14 @@ async function register(options) {
|
|
|
917
923
|
try {
|
|
918
924
|
if (hasExistingToken) {
|
|
919
925
|
if (!options.json) {
|
|
920
|
-
console.log("Step 1:
|
|
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 {
|
|
926
|
+
console.log("Step 1: Using existing token...\n");
|
|
935
927
|
}
|
|
936
928
|
tokenAddress = options.token;
|
|
937
|
-
flaunchUrl = `https://flaunch.gg/base/coin/${options.token}`;
|
|
938
929
|
if (!options.json) {
|
|
939
|
-
console.log(` \u2713 Token: ${tokenAddress}
|
|
940
|
-
console.log(` \u2713 URL: ${flaunchUrl}
|
|
930
|
+
console.log(` \u2713 Token: ${tokenAddress}
|
|
941
931
|
`);
|
|
942
932
|
}
|
|
943
|
-
} else {
|
|
933
|
+
} else if (options.symbol) {
|
|
944
934
|
if (!options.json) {
|
|
945
935
|
console.log("Step 1: Launching token on Base...\n");
|
|
946
936
|
}
|
|
@@ -962,6 +952,10 @@ async function register(options) {
|
|
|
962
952
|
console.log(` \u2713 TX: ${tokenTxHash}
|
|
963
953
|
`);
|
|
964
954
|
}
|
|
955
|
+
} else {
|
|
956
|
+
if (!options.json) {
|
|
957
|
+
console.log("Step 1: Skipped (no token \u2014 direct ETH payment)\n");
|
|
958
|
+
}
|
|
965
959
|
}
|
|
966
960
|
if (!options.json) {
|
|
967
961
|
console.log("Step 2: Registering agent identity...\n");
|
|
@@ -976,7 +970,7 @@ async function register(options) {
|
|
|
976
970
|
skills,
|
|
977
971
|
endpoint: options.endpoint || "",
|
|
978
972
|
priceWei: parseEther(options.price),
|
|
979
|
-
flaunchToken: tokenAddress
|
|
973
|
+
flaunchToken: tokenAddress ? tokenAddress : void 0
|
|
980
974
|
});
|
|
981
975
|
let registrationStatus = "unknown";
|
|
982
976
|
try {
|
|
@@ -1035,8 +1029,12 @@ async function register(options) {
|
|
|
1035
1029
|
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
1030
|
console.log(`Agent ID: ${agentResult.agentId}`);
|
|
1037
1031
|
console.log(`Name: ${options.name}`);
|
|
1038
|
-
|
|
1039
|
-
|
|
1032
|
+
if (tokenAddress) {
|
|
1033
|
+
console.log(`Token: ${symbol ? `$${symbol}` : tokenAddress}`);
|
|
1034
|
+
console.log(`Address: ${tokenAddress}`);
|
|
1035
|
+
} else {
|
|
1036
|
+
console.log(`Token: (none \u2014 direct ETH payment)`);
|
|
1037
|
+
}
|
|
1040
1038
|
console.log(`Skills: ${skills.join(", ")}`);
|
|
1041
1039
|
if (options.endpoint) {
|
|
1042
1040
|
console.log(`Endpoint: ${options.endpoint}`);
|
|
@@ -1047,7 +1045,11 @@ async function register(options) {
|
|
|
1047
1045
|
console.log(`Wallet: ${wallet2.address}`);
|
|
1048
1046
|
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
1047
|
console.log("\nLinks:");
|
|
1050
|
-
|
|
1048
|
+
if (flaunchUrl) {
|
|
1049
|
+
console.log(` Token: ${flaunchUrl}`);
|
|
1050
|
+
} else if (tokenAddress) {
|
|
1051
|
+
console.log(` Token: https://basescan.org/token/${tokenAddress}`);
|
|
1052
|
+
}
|
|
1051
1053
|
if (tokenTxHash) {
|
|
1052
1054
|
console.log(` Token TX: ${CHAIN.explorer}/tx/${tokenTxHash}`);
|
|
1053
1055
|
}
|
|
@@ -1062,8 +1064,10 @@ async function register(options) {
|
|
|
1062
1064
|
console.log("\nTo receive work requests, run:");
|
|
1063
1065
|
console.log(` mltl inbox --agent ${agentResult.agentId}`);
|
|
1064
1066
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
+
if (flaunchUrl) {
|
|
1068
|
+
console.log("\nOthers can invest in your agent at:");
|
|
1069
|
+
console.log(` ${flaunchUrl}`);
|
|
1070
|
+
}
|
|
1067
1071
|
if (registrationStatus === "pending") {
|
|
1068
1072
|
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
1073
|
console.log("\n\u23F3 Your agent is pending admin approval.");
|
|
@@ -1809,8 +1813,9 @@ async function earnings(options) {
|
|
|
1809
1813
|
console.log(` Feedback received: ${feedbackCount}`);
|
|
1810
1814
|
console.log(` Average score: ${avgScore > 0 ? avgScore.toFixed(1) + "/100" : "N/A"}`);
|
|
1811
1815
|
console.log("");
|
|
1812
|
-
console.log("
|
|
1813
|
-
console.log("
|
|
1816
|
+
console.log("Completed tasks pay out when the client approves work.");
|
|
1817
|
+
console.log("Agents with a token receive payment via buyback-and-burn.");
|
|
1818
|
+
console.log("Agents without a token receive ETH directly.");
|
|
1814
1819
|
} catch (err) {
|
|
1815
1820
|
if (options.json) {
|
|
1816
1821
|
console.log(
|
|
@@ -1954,7 +1959,7 @@ async function fees(options) {
|
|
|
1954
1959
|
console.log("");
|
|
1955
1960
|
if (tokens.length === 0) {
|
|
1956
1961
|
console.log("No tokens found for this wallet in the Revenue Manager.");
|
|
1957
|
-
console.log("
|
|
1962
|
+
console.log("Trading fees only apply to agents with a Flaunch token (registered with --symbol).");
|
|
1958
1963
|
} else if (balance === 0n) {
|
|
1959
1964
|
console.log("No fees to claim yet. Fees accumulate from token trading activity.");
|
|
1960
1965
|
} else {
|
|
@@ -1968,6 +1973,7 @@ async function fees(options) {
|
|
|
1968
1973
|
process.exit(1);
|
|
1969
1974
|
}
|
|
1970
1975
|
console.log("No tokens found for this wallet in the Revenue Manager.");
|
|
1976
|
+
console.log("Trading fees only apply to agents with a Flaunch token (registered with --symbol).");
|
|
1971
1977
|
return;
|
|
1972
1978
|
}
|
|
1973
1979
|
if (balance === 0n) {
|
|
@@ -2428,10 +2434,7 @@ async function accept(options) {
|
|
|
2428
2434
|
if (!agentOwner) {
|
|
2429
2435
|
throw new Error("Agent has no owner address");
|
|
2430
2436
|
}
|
|
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
|
-
}
|
|
2437
|
+
const agentToken = agent.flaunchToken || "0x0000000000000000000000000000000000000001";
|
|
2435
2438
|
const priceWei = BigInt(taskBefore.quotedPriceWei || "0");
|
|
2436
2439
|
const balance = await getWalletBalance(wallet2.address);
|
|
2437
2440
|
const balanceWei = parseEther2(balance);
|
|
@@ -2456,7 +2459,7 @@ ${taskBefore.task}
|
|
|
2456
2459
|
console.log(`
|
|
2457
2460
|
This will deposit ${priceEth} ETH into escrow.`);
|
|
2458
2461
|
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");
|
|
2462
|
+
console.log(agent.flaunchToken ? " - Approve submitted work: funds buy back & burn agent's token" : " - Approve submitted work: funds released directly to agent");
|
|
2460
2463
|
console.log(" - Cancel before submission: 10% fee to agent, 90% refunded");
|
|
2461
2464
|
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
2465
|
console.log("\nDepositing funds into escrow...");
|
|
@@ -2496,7 +2499,7 @@ This will deposit ${priceEth} ETH into escrow.`);
|
|
|
2496
2499
|
console.log("\n\u2705 Quote accepted! Funds locked in escrow.");
|
|
2497
2500
|
console.log(`
|
|
2498
2501
|
Escrow: ${priceEth} ETH deposited`);
|
|
2499
|
-
console.log(`Token: ${
|
|
2502
|
+
console.log(`Token: ${agent.flaunchToken || "(none \u2014 direct ETH payment)"}`);
|
|
2500
2503
|
console.log(`TX: ${escrowTxHash}`);
|
|
2501
2504
|
console.log("\nThe agent can now begin work. When they submit:");
|
|
2502
2505
|
console.log(" - Review & approve: mltl approve --task " + task.id);
|
|
@@ -4079,7 +4082,7 @@ async function verifyX(options) {
|
|
|
4079
4082
|
// src/index.ts
|
|
4080
4083
|
var program = new Command();
|
|
4081
4084
|
program.name("mltl").description("moltlaunch \u2014 hire AI agents with onchain reputation").version("2.8.0");
|
|
4082
|
-
program.command("register").description("Register an agent (
|
|
4085
|
+
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
4086
|
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
4087
|
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
4088
|
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);
|