arc402-cli 0.2.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 +245 -0
- package/dist/abis.d.ts +19 -0
- package/dist/abis.d.ts.map +1 -0
- package/dist/abis.js +177 -0
- package/dist/abis.js.map +1 -0
- package/dist/bundler.d.ts +65 -0
- package/dist/bundler.d.ts.map +1 -0
- package/dist/bundler.js +181 -0
- package/dist/bundler.js.map +1 -0
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +24 -0
- package/dist/client.js.map +1 -0
- package/dist/coinbase-smart-wallet.d.ts +28 -0
- package/dist/coinbase-smart-wallet.d.ts.map +1 -0
- package/dist/coinbase-smart-wallet.js +38 -0
- package/dist/coinbase-smart-wallet.js.map +1 -0
- package/dist/commands/accept.d.ts +3 -0
- package/dist/commands/accept.d.ts.map +1 -0
- package/dist/commands/accept.js +26 -0
- package/dist/commands/accept.js.map +1 -0
- package/dist/commands/agent-handshake.d.ts +3 -0
- package/dist/commands/agent-handshake.d.ts.map +1 -0
- package/dist/commands/agent-handshake.js +61 -0
- package/dist/commands/agent-handshake.js.map +1 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +417 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/agreements.d.ts +3 -0
- package/dist/commands/agreements.d.ts.map +1 -0
- package/dist/commands/agreements.js +344 -0
- package/dist/commands/agreements.js.map +1 -0
- package/dist/commands/arbitrator.d.ts +3 -0
- package/dist/commands/arbitrator.d.ts.map +1 -0
- package/dist/commands/arbitrator.js +157 -0
- package/dist/commands/arbitrator.js.map +1 -0
- package/dist/commands/arena-handshake.d.ts +3 -0
- package/dist/commands/arena-handshake.d.ts.map +1 -0
- package/dist/commands/arena-handshake.js +187 -0
- package/dist/commands/arena-handshake.js.map +1 -0
- package/dist/commands/cancel.d.ts +3 -0
- package/dist/commands/cancel.d.ts.map +1 -0
- package/dist/commands/cancel.js +30 -0
- package/dist/commands/cancel.js.map +1 -0
- package/dist/commands/channel.d.ts +3 -0
- package/dist/commands/channel.d.ts.map +1 -0
- package/dist/commands/channel.js +238 -0
- package/dist/commands/channel.js.map +1 -0
- package/dist/commands/coldstart.d.ts +3 -0
- package/dist/commands/coldstart.d.ts.map +1 -0
- package/dist/commands/coldstart.js +148 -0
- package/dist/commands/coldstart.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +40 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/contract-interaction.d.ts +3 -0
- package/dist/commands/contract-interaction.d.ts.map +1 -0
- package/dist/commands/contract-interaction.js +165 -0
- package/dist/commands/contract-interaction.js.map +1 -0
- package/dist/commands/daemon.d.ts +3 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +891 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/deliver.d.ts +3 -0
- package/dist/commands/deliver.d.ts.map +1 -0
- package/dist/commands/deliver.js +156 -0
- package/dist/commands/deliver.js.map +1 -0
- package/dist/commands/discover.d.ts +3 -0
- package/dist/commands/discover.d.ts.map +1 -0
- package/dist/commands/discover.js +224 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/dispute.d.ts +3 -0
- package/dist/commands/dispute.d.ts.map +1 -0
- package/dist/commands/dispute.js +348 -0
- package/dist/commands/dispute.js.map +1 -0
- package/dist/commands/endpoint.d.ts +3 -0
- package/dist/commands/endpoint.d.ts.map +1 -0
- package/dist/commands/endpoint.js +604 -0
- package/dist/commands/endpoint.js.map +1 -0
- package/dist/commands/hire.d.ts +3 -0
- package/dist/commands/hire.d.ts.map +1 -0
- package/dist/commands/hire.js +189 -0
- package/dist/commands/hire.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +163 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/negotiate.d.ts +3 -0
- package/dist/commands/negotiate.d.ts.map +1 -0
- package/dist/commands/negotiate.js +247 -0
- package/dist/commands/negotiate.js.map +1 -0
- package/dist/commands/openshell.d.ts +3 -0
- package/dist/commands/openshell.d.ts.map +1 -0
- package/dist/commands/openshell.js +952 -0
- package/dist/commands/openshell.js.map +1 -0
- package/dist/commands/owner.d.ts +3 -0
- package/dist/commands/owner.d.ts.map +1 -0
- package/dist/commands/owner.js +32 -0
- package/dist/commands/owner.js.map +1 -0
- package/dist/commands/policy.d.ts +4 -0
- package/dist/commands/policy.d.ts.map +1 -0
- package/dist/commands/policy.js +248 -0
- package/dist/commands/policy.js.map +1 -0
- package/dist/commands/relay.d.ts +3 -0
- package/dist/commands/relay.d.ts.map +1 -0
- package/dist/commands/relay.js +279 -0
- package/dist/commands/relay.js.map +1 -0
- package/dist/commands/remediate.d.ts +3 -0
- package/dist/commands/remediate.d.ts.map +1 -0
- package/dist/commands/remediate.js +42 -0
- package/dist/commands/remediate.js.map +1 -0
- package/dist/commands/reputation.d.ts +4 -0
- package/dist/commands/reputation.d.ts.map +1 -0
- package/dist/commands/reputation.js +72 -0
- package/dist/commands/reputation.js.map +1 -0
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +332 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/trust.d.ts +3 -0
- package/dist/commands/trust.d.ts.map +1 -0
- package/dist/commands/trust.js +23 -0
- package/dist/commands/trust.js.map +1 -0
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +88 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/wallet.d.ts +3 -0
- package/dist/commands/wallet.d.ts.map +1 -0
- package/dist/commands/wallet.js +2520 -0
- package/dist/commands/wallet.js.map +1 -0
- package/dist/commands/watchtower.d.ts +3 -0
- package/dist/commands/watchtower.d.ts.map +1 -0
- package/dist/commands/watchtower.js +238 -0
- package/dist/commands/watchtower.js.map +1 -0
- package/dist/commands/workroom.d.ts +3 -0
- package/dist/commands/workroom.d.ts.map +1 -0
- package/dist/commands/workroom.js +855 -0
- package/dist/commands/workroom.js.map +1 -0
- package/dist/config.d.ts +62 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +141 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/config.d.ts +74 -0
- package/dist/daemon/config.d.ts.map +1 -0
- package/dist/daemon/config.js +271 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/hire-listener.d.ts +31 -0
- package/dist/daemon/hire-listener.d.ts.map +1 -0
- package/dist/daemon/hire-listener.js +207 -0
- package/dist/daemon/hire-listener.js.map +1 -0
- package/dist/daemon/index.d.ts +29 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +535 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/job-lifecycle.d.ts +62 -0
- package/dist/daemon/job-lifecycle.d.ts.map +1 -0
- package/dist/daemon/job-lifecycle.js +201 -0
- package/dist/daemon/job-lifecycle.js.map +1 -0
- package/dist/daemon/notify.d.ts +22 -0
- package/dist/daemon/notify.d.ts.map +1 -0
- package/dist/daemon/notify.js +148 -0
- package/dist/daemon/notify.js.map +1 -0
- package/dist/daemon/token-metering.d.ts +42 -0
- package/dist/daemon/token-metering.d.ts.map +1 -0
- package/dist/daemon/token-metering.js +178 -0
- package/dist/daemon/token-metering.js.map +1 -0
- package/dist/daemon/userops.d.ts +21 -0
- package/dist/daemon/userops.d.ts.map +1 -0
- package/dist/daemon/userops.js +88 -0
- package/dist/daemon/userops.js.map +1 -0
- package/dist/daemon/wallet-monitor.d.ts +16 -0
- package/dist/daemon/wallet-monitor.d.ts.map +1 -0
- package/dist/daemon/wallet-monitor.js +57 -0
- package/dist/daemon/wallet-monitor.js.map +1 -0
- package/dist/drain-v4.d.ts +2 -0
- package/dist/drain-v4.d.ts.map +1 -0
- package/dist/drain-v4.js +167 -0
- package/dist/drain-v4.js.map +1 -0
- package/dist/endpoint-config.d.ts +36 -0
- package/dist/endpoint-config.d.ts.map +1 -0
- package/dist/endpoint-config.js +96 -0
- package/dist/endpoint-config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/openshell-runtime.d.ts +55 -0
- package/dist/openshell-runtime.d.ts.map +1 -0
- package/dist/openshell-runtime.js +268 -0
- package/dist/openshell-runtime.js.map +1 -0
- package/dist/signing.d.ts +2 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +23 -0
- package/dist/signing.js.map +1 -0
- package/dist/telegram-notify.d.ts +23 -0
- package/dist/telegram-notify.d.ts.map +1 -0
- package/dist/telegram-notify.js +106 -0
- package/dist/telegram-notify.js.map +1 -0
- package/dist/ui/banner.d.ts +7 -0
- package/dist/ui/banner.d.ts.map +1 -0
- package/dist/ui/banner.js +37 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/colors.d.ts +14 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +29 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/format.d.ts +26 -0
- package/dist/ui/format.d.ts.map +1 -0
- package/dist/ui/format.js +77 -0
- package/dist/ui/format.js.map +1 -0
- package/dist/ui/spinner.d.ts +8 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +43 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/utils/format.d.ts +10 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +61 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +43 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/time.d.ts +3 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +21 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/wallet-router.d.ts +25 -0
- package/dist/wallet-router.d.ts.map +1 -0
- package/dist/wallet-router.js +153 -0
- package/dist/wallet-router.js.map +1 -0
- package/dist/walletconnect-session.d.ts +12 -0
- package/dist/walletconnect-session.d.ts.map +1 -0
- package/dist/walletconnect-session.js +26 -0
- package/dist/walletconnect-session.js.map +1 -0
- package/dist/walletconnect.d.ts +46 -0
- package/dist/walletconnect.d.ts.map +1 -0
- package/dist/walletconnect.js +267 -0
- package/dist/walletconnect.js.map +1 -0
- package/package.json +38 -0
- package/scripts/authorize-machine-key.ts +43 -0
- package/scripts/drain-wallet.ts +149 -0
- package/scripts/execute-spend-only.ts +81 -0
- package/scripts/register-agent-userop.ts +186 -0
- package/src/abis.ts +187 -0
- package/src/bundler.ts +235 -0
- package/src/client.ts +34 -0
- package/src/coinbase-smart-wallet.ts +51 -0
- package/src/commands/accept.ts +25 -0
- package/src/commands/agent-handshake.ts +67 -0
- package/src/commands/agent.ts +458 -0
- package/src/commands/agreements.ts +324 -0
- package/src/commands/arbitrator.ts +129 -0
- package/src/commands/arena-handshake.ts +217 -0
- package/src/commands/cancel.ts +26 -0
- package/src/commands/channel.ts +208 -0
- package/src/commands/coldstart.ts +156 -0
- package/src/commands/config.ts +35 -0
- package/src/commands/contract-interaction.ts +166 -0
- package/src/commands/daemon.ts +971 -0
- package/src/commands/deliver.ts +116 -0
- package/src/commands/discover.ts +295 -0
- package/src/commands/dispute.ts +373 -0
- package/src/commands/endpoint.ts +619 -0
- package/src/commands/hire.ts +200 -0
- package/src/commands/migrate.ts +175 -0
- package/src/commands/negotiate.ts +270 -0
- package/src/commands/openshell.ts +1053 -0
- package/src/commands/owner.ts +30 -0
- package/src/commands/policy.ts +252 -0
- package/src/commands/relay.ts +272 -0
- package/src/commands/remediate.ts +22 -0
- package/src/commands/reputation.ts +71 -0
- package/src/commands/setup.ts +343 -0
- package/src/commands/trust.ts +15 -0
- package/src/commands/verify.ts +88 -0
- package/src/commands/wallet.ts +2892 -0
- package/src/commands/watchtower.ts +232 -0
- package/src/commands/workroom.ts +889 -0
- package/src/config.ts +153 -0
- package/src/daemon/config.ts +308 -0
- package/src/daemon/hire-listener.ts +226 -0
- package/src/daemon/index.ts +609 -0
- package/src/daemon/job-lifecycle.ts +215 -0
- package/src/daemon/notify.ts +157 -0
- package/src/daemon/token-metering.ts +183 -0
- package/src/daemon/userops.ts +119 -0
- package/src/daemon/wallet-monitor.ts +90 -0
- package/src/drain-v4.ts +159 -0
- package/src/endpoint-config.ts +83 -0
- package/src/index.ts +75 -0
- package/src/openshell-runtime.ts +277 -0
- package/src/signing.ts +28 -0
- package/src/telegram-notify.ts +88 -0
- package/src/ui/banner.ts +41 -0
- package/src/ui/colors.ts +30 -0
- package/src/ui/format.ts +77 -0
- package/src/ui/spinner.ts +46 -0
- package/src/utils/format.ts +48 -0
- package/src/utils/hash.ts +5 -0
- package/src/utils/time.ts +15 -0
- package/src/wallet-router.ts +178 -0
- package/src/walletconnect-session.ts +27 -0
- package/src/walletconnect.ts +294 -0
- package/test/time.test.js +11 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerHireCommand = registerHireCommand;
|
|
4
|
+
const sdk_1 = require("@arc402/sdk");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const client_1 = require("../client");
|
|
8
|
+
const hash_1 = require("../utils/hash");
|
|
9
|
+
const time_1 = require("../utils/time");
|
|
10
|
+
const wallet_router_1 = require("../wallet-router");
|
|
11
|
+
const abis_1 = require("../abis");
|
|
12
|
+
const sessionManager = new sdk_1.SessionManager();
|
|
13
|
+
function registerHireCommand(program) {
|
|
14
|
+
program
|
|
15
|
+
.command("hire")
|
|
16
|
+
.description("Create the on-chain commitment after off-chain negotiation")
|
|
17
|
+
.requiredOption("--agent <address>")
|
|
18
|
+
.requiredOption("--task <description>")
|
|
19
|
+
.requiredOption("--service-type <type>")
|
|
20
|
+
.option("--max <amount>", "Max price in wei (e.g. 1000000000000000) or ETH (e.g. 0.001eth) or USDC (e.g. 1USDC). Required unless --session is provided.")
|
|
21
|
+
.option("--deadline <duration>", "Deadline as duration (1h, 30m, 7d) or absolute ISO date (2026-04-01). Required unless --session is provided.")
|
|
22
|
+
.option("--token <token>", "eth or usdc", "eth")
|
|
23
|
+
.option("--deliverable-spec <filepath>")
|
|
24
|
+
.option("--session <sessionId>", "Load agreed price and deadline from a completed negotiation session")
|
|
25
|
+
.option("--json")
|
|
26
|
+
.action(async (opts) => {
|
|
27
|
+
const config = (0, config_1.loadConfig)();
|
|
28
|
+
if (!config.serviceAgreementAddress)
|
|
29
|
+
throw new Error("serviceAgreementAddress missing in config");
|
|
30
|
+
const { signer, address } = await (0, client_1.requireSigner)(config);
|
|
31
|
+
const client = new sdk_1.ServiceAgreementClient(config.serviceAgreementAddress, signer);
|
|
32
|
+
let maxAmount;
|
|
33
|
+
let deadlineArg;
|
|
34
|
+
let transcriptHash;
|
|
35
|
+
if (opts.session) {
|
|
36
|
+
const session = sessionManager.load(opts.session);
|
|
37
|
+
if (session.state !== "ACCEPTED")
|
|
38
|
+
throw new Error(`Session ${opts.session} is not in ACCEPTED state (state: ${session.state})`);
|
|
39
|
+
if (!session.agreedPrice || !session.agreedDeadline)
|
|
40
|
+
throw new Error(`Session ${opts.session} is missing agreedPrice or agreedDeadline`);
|
|
41
|
+
maxAmount = session.agreedPrice;
|
|
42
|
+
deadlineArg = session.agreedDeadline;
|
|
43
|
+
transcriptHash = session.transcriptHash;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
if (!opts.max)
|
|
47
|
+
throw new Error("--max is required when --session is not provided. Examples: 0.001eth, 1000000000000000 (wei), 1USDC");
|
|
48
|
+
if (!opts.deadline)
|
|
49
|
+
throw new Error("--deadline is required when --session is not provided. Examples: 1h, 30m, 7d, 2026-04-01");
|
|
50
|
+
maxAmount = opts.max;
|
|
51
|
+
deadlineArg = opts.deadline;
|
|
52
|
+
}
|
|
53
|
+
// Normalise --max: strip trailing 'eth' or 'USDC' suffix and convert to correct unit
|
|
54
|
+
const useUsdc = String(opts.token).toLowerCase() === "usdc";
|
|
55
|
+
const ethSuffix = /^(\d+(?:\.\d+)?)eth$/i.exec(maxAmount);
|
|
56
|
+
const usdcSuffix = /^(\d+(?:\.\d+)?)usdc$/i.exec(maxAmount);
|
|
57
|
+
if (ethSuffix)
|
|
58
|
+
maxAmount = String(BigInt(Math.round(parseFloat(ethSuffix[1]) * 1e18)));
|
|
59
|
+
else if (usdcSuffix)
|
|
60
|
+
maxAmount = usdcSuffix[1]; // keep decimal for USDC path
|
|
61
|
+
const token = useUsdc ? (0, config_1.getUsdcAddress)(config) : ethers_1.ethers.ZeroAddress;
|
|
62
|
+
let price;
|
|
63
|
+
try {
|
|
64
|
+
price = useUsdc ? BigInt(Math.round(Number(maxAmount) * 1000000)) : BigInt(maxAmount);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
throw new Error(`Invalid --max value "${opts.max}". Use wei (1000000000000000), ETH (0.001eth), or USDC (1USDC)`);
|
|
68
|
+
}
|
|
69
|
+
if (price <= 0n)
|
|
70
|
+
throw new Error(`--max must be greater than zero`);
|
|
71
|
+
// Pre-flight: check client !== provider (J2-03)
|
|
72
|
+
if (address.toLowerCase() === opts.agent.toLowerCase()) {
|
|
73
|
+
console.error("Cannot hire yourself: client and provider addresses are the same.");
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
// Pre-flight: check provider is registered in AgentRegistry (J2-02)
|
|
77
|
+
const agentRegistryAddress = config.agentRegistryV2Address ?? config.agentRegistryAddress;
|
|
78
|
+
if (agentRegistryAddress) {
|
|
79
|
+
const arProvider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
80
|
+
const arCheck = new ethers_1.ethers.Contract(agentRegistryAddress, ["function isRegistered(address wallet) external view returns (bool)"], arProvider);
|
|
81
|
+
let isRegistered = true;
|
|
82
|
+
try {
|
|
83
|
+
isRegistered = await arCheck.isRegistered(opts.agent);
|
|
84
|
+
}
|
|
85
|
+
catch { /* assume registered if read fails */ }
|
|
86
|
+
if (!isRegistered) {
|
|
87
|
+
console.error(`Provider ${opts.agent} is not registered in AgentRegistry.`);
|
|
88
|
+
console.error(`Verify the agent address is correct, or check the registry at ${agentRegistryAddress}.`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Pre-flight: check token is allowed on this ServiceAgreement (J2-01)
|
|
93
|
+
if (useUsdc) {
|
|
94
|
+
const saProvider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
95
|
+
const saCheck = new ethers_1.ethers.Contract(config.serviceAgreementAddress, ["function allowedTokens(address) external view returns (bool)"], saProvider);
|
|
96
|
+
let isAllowed = false;
|
|
97
|
+
try {
|
|
98
|
+
isAllowed = await saCheck.allowedTokens(token);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
isAllowed = true; /* assume allowed if read fails */
|
|
102
|
+
}
|
|
103
|
+
if (!isAllowed) {
|
|
104
|
+
console.error(`Token ${token} is not allowed on this ServiceAgreement.`);
|
|
105
|
+
console.error(`Only the SA owner can allowlist tokens via:`);
|
|
106
|
+
console.error(` cast send ${config.serviceAgreementAddress} "allowToken(address)" ${token}`);
|
|
107
|
+
console.error(`For ETH payments, use --token eth`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Use spec hash as deliverables hash; if transcript exists, incorporate it
|
|
112
|
+
const baseHash = opts.deliverableSpec ? (0, hash_1.hashFile)(opts.deliverableSpec) : (0, hash_1.hashString)(opts.task);
|
|
113
|
+
const deliverablesHash = transcriptHash
|
|
114
|
+
? ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(baseHash + transcriptHash))
|
|
115
|
+
: baseHash;
|
|
116
|
+
// Parse deadline: if it looks like an ISO date, convert to seconds from now
|
|
117
|
+
let deadlineSeconds;
|
|
118
|
+
const isoMatch = deadlineArg.match(/^\d{4}-\d{2}-\d{2}/);
|
|
119
|
+
if (isoMatch) {
|
|
120
|
+
const target = Math.floor(new Date(deadlineArg).getTime() / 1000);
|
|
121
|
+
deadlineSeconds = target - Math.floor(Date.now() / 1000);
|
|
122
|
+
if (deadlineSeconds <= 0)
|
|
123
|
+
throw new Error(`Deadline ${deadlineArg} is in the past`);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
deadlineSeconds = (0, time_1.parseDuration)(deadlineArg);
|
|
127
|
+
}
|
|
128
|
+
(0, wallet_router_1.printSenderInfo)(config);
|
|
129
|
+
let agreementId;
|
|
130
|
+
if (config.walletContractAddress) {
|
|
131
|
+
// Smart wallet path — wallet handles per-tx USDC approval via maxApprovalAmount
|
|
132
|
+
const tx = await (0, wallet_router_1.executeContractWriteViaWallet)(config.walletContractAddress, signer, config.serviceAgreementAddress, abis_1.SERVICE_AGREEMENT_ABI, "propose", [opts.agent, opts.serviceType, opts.task, price, token, deadlineSeconds, deliverablesHash], useUsdc ? 0n : price, // ETH value forwarded to SA; 0 for USDC agreements
|
|
133
|
+
useUsdc ? token : ethers_1.ethers.ZeroAddress, // approvalToken for USDC
|
|
134
|
+
useUsdc ? price : 0n);
|
|
135
|
+
const receipt = await tx.wait();
|
|
136
|
+
const saInterface = new ethers_1.ethers.Interface(abis_1.SERVICE_AGREEMENT_ABI);
|
|
137
|
+
let found = false;
|
|
138
|
+
for (const log of receipt.logs) {
|
|
139
|
+
if (log.address.toLowerCase() === config.serviceAgreementAddress.toLowerCase()) {
|
|
140
|
+
try {
|
|
141
|
+
const parsed = saInterface.parseLog(log);
|
|
142
|
+
if (parsed?.name === "AgreementProposed") {
|
|
143
|
+
agreementId = parsed.args[0];
|
|
144
|
+
found = true;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch { /* skip unparseable logs */ }
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (!found)
|
|
152
|
+
throw new Error("AgreementProposed event not found in transaction receipt");
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// EOA path — existing behaviour
|
|
156
|
+
if (useUsdc) {
|
|
157
|
+
const usdc = new ethers_1.ethers.Contract(token, ["function approve(address spender,uint256 amount) external returns (bool)", "function allowance(address owner,address spender) external view returns (uint256)"], signer);
|
|
158
|
+
const allowance = await usdc.allowance(address, config.serviceAgreementAddress);
|
|
159
|
+
if (allowance < price)
|
|
160
|
+
await (await usdc.approve(config.serviceAgreementAddress, price)).wait();
|
|
161
|
+
}
|
|
162
|
+
const result = await client.propose({
|
|
163
|
+
provider: opts.agent,
|
|
164
|
+
serviceType: opts.serviceType,
|
|
165
|
+
description: opts.task,
|
|
166
|
+
price,
|
|
167
|
+
token,
|
|
168
|
+
deadline: deadlineSeconds,
|
|
169
|
+
deliverablesHash,
|
|
170
|
+
});
|
|
171
|
+
agreementId = result.agreementId;
|
|
172
|
+
}
|
|
173
|
+
if (opts.session) {
|
|
174
|
+
sessionManager.setOnChainId(opts.session, agreementId.toString());
|
|
175
|
+
}
|
|
176
|
+
if (opts.json) {
|
|
177
|
+
const output = { agreementId: agreementId.toString(), deliverablesHash };
|
|
178
|
+
if (transcriptHash)
|
|
179
|
+
output.transcriptHash = transcriptHash;
|
|
180
|
+
if (opts.session)
|
|
181
|
+
output.sessionId = opts.session;
|
|
182
|
+
return console.log(JSON.stringify(output, null, 2));
|
|
183
|
+
}
|
|
184
|
+
console.log(`agreementId=${agreementId} deliverablesHash=${deliverablesHash}`);
|
|
185
|
+
if (transcriptHash)
|
|
186
|
+
console.log(`transcriptHash=${transcriptHash}`);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=hire.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hire.js","sourceRoot":"","sources":["../../src/commands/hire.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgK9D"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerMigrateCommands = registerMigrateCommands;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const config_1 = require("../config");
|
|
6
|
+
const client_1 = require("../client");
|
|
7
|
+
const MIGRATION_REGISTRY_ABI = [
|
|
8
|
+
"function registerMigration(address oldWallet, address newWallet) external",
|
|
9
|
+
"function resolveActiveWallet(address wallet) external view returns (address)",
|
|
10
|
+
"function getLineage(address wallet) external view returns (address[])",
|
|
11
|
+
"function migratedTo(address wallet) external view returns (address)",
|
|
12
|
+
"function migratedFrom(address wallet) external view returns (address)",
|
|
13
|
+
"event MigrationRegistered(address indexed oldWallet, address indexed newWallet, address indexed owner, uint256 migratedAt, uint256 scoreAtMigration, uint256 appliedDecay)",
|
|
14
|
+
];
|
|
15
|
+
function registerMigrateCommands(program) {
|
|
16
|
+
const migrate = program
|
|
17
|
+
.command("migrate")
|
|
18
|
+
.description("Wallet migration — register, query status, or print lineage history")
|
|
19
|
+
.argument("[oldWallet]", "old wallet address (required for registration)")
|
|
20
|
+
.argument("[newWallet]", "new wallet address (required for registration)")
|
|
21
|
+
.option("--json")
|
|
22
|
+
.action(async (oldWallet, newWallet, opts) => {
|
|
23
|
+
if (!oldWallet || !newWallet) {
|
|
24
|
+
console.error("Usage: arc402 migrate <oldWallet> <newWallet>");
|
|
25
|
+
console.error("Both wallets must share the same registered owner address.");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const config = (0, config_1.loadConfig)();
|
|
29
|
+
if (!config.migrationRegistryAddress) {
|
|
30
|
+
console.error("migrationRegistryAddress not configured. Run `arc402 config set migrationRegistryAddress <address>`.");
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
34
|
+
const contract = new ethers_1.ethers.Contract(config.migrationRegistryAddress, MIGRATION_REGISTRY_ABI, signer);
|
|
35
|
+
const tx = await contract.registerMigration(oldWallet, newWallet);
|
|
36
|
+
const receipt = await tx.wait();
|
|
37
|
+
const payload = {
|
|
38
|
+
oldWallet,
|
|
39
|
+
newWallet,
|
|
40
|
+
txHash: receipt.hash,
|
|
41
|
+
};
|
|
42
|
+
if (opts.json)
|
|
43
|
+
return console.log(JSON.stringify(payload, null, 2));
|
|
44
|
+
console.log(`migration registered`);
|
|
45
|
+
console.log(` old: ${oldWallet}`);
|
|
46
|
+
console.log(` new: ${newWallet}`);
|
|
47
|
+
console.log(` note: 10% trust score decay applied on migration`);
|
|
48
|
+
console.log(` tx: ${receipt.hash}`);
|
|
49
|
+
});
|
|
50
|
+
// ─── migrate status <address> ──────────────────────────────────────────────
|
|
51
|
+
migrate
|
|
52
|
+
.command("status <address>")
|
|
53
|
+
.description("Show whether a wallet is in a migration lineage and its current active wallet")
|
|
54
|
+
.option("--json")
|
|
55
|
+
.action(async (address, opts) => {
|
|
56
|
+
const config = (0, config_1.loadConfig)();
|
|
57
|
+
if (!config.migrationRegistryAddress) {
|
|
58
|
+
console.error("migrationRegistryAddress not configured. Run `arc402 config set migrationRegistryAddress <address>`.");
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const { provider } = await (0, client_1.getClient)(config);
|
|
62
|
+
const contract = new ethers_1.ethers.Contract(config.migrationRegistryAddress, MIGRATION_REGISTRY_ABI, provider);
|
|
63
|
+
const [activeWallet, migratedTo, migratedFrom] = await Promise.all([
|
|
64
|
+
contract.resolveActiveWallet(address),
|
|
65
|
+
contract.migratedTo(address),
|
|
66
|
+
contract.migratedFrom(address),
|
|
67
|
+
]);
|
|
68
|
+
const isCurrent = activeWallet.toLowerCase() === address.toLowerCase();
|
|
69
|
+
const hasMigrated = migratedTo !== ethers_1.ethers.ZeroAddress;
|
|
70
|
+
const wasSource = migratedFrom !== ethers_1.ethers.ZeroAddress;
|
|
71
|
+
const payload = {
|
|
72
|
+
address,
|
|
73
|
+
activeWallet,
|
|
74
|
+
isCurrent,
|
|
75
|
+
migratedTo: hasMigrated ? migratedTo : null,
|
|
76
|
+
migratedFrom: wasSource ? migratedFrom : null,
|
|
77
|
+
};
|
|
78
|
+
if (opts.json)
|
|
79
|
+
return console.log(JSON.stringify(payload, null, 2));
|
|
80
|
+
console.log(`address=${address}`);
|
|
81
|
+
console.log(` active wallet: ${activeWallet}`);
|
|
82
|
+
if (isCurrent) {
|
|
83
|
+
console.log(` status: current (no further migration)`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
console.log(` status: migrated — score queries resolve to ${activeWallet}`);
|
|
87
|
+
}
|
|
88
|
+
if (hasMigrated)
|
|
89
|
+
console.log(` migrated to: ${migratedTo}`);
|
|
90
|
+
if (wasSource)
|
|
91
|
+
console.log(` migrated from: ${migratedFrom}`);
|
|
92
|
+
});
|
|
93
|
+
// ─── migrate lineage <address> ────────────────────────────────────────────
|
|
94
|
+
migrate
|
|
95
|
+
.command("lineage <address>")
|
|
96
|
+
.description("Print full migration lineage history with timestamps")
|
|
97
|
+
.option("--json")
|
|
98
|
+
.action(async (address, opts) => {
|
|
99
|
+
const config = (0, config_1.loadConfig)();
|
|
100
|
+
if (!config.migrationRegistryAddress) {
|
|
101
|
+
console.error("migrationRegistryAddress not configured. Run `arc402 config set migrationRegistryAddress <address>`.");
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const { provider } = await (0, client_1.getClient)(config);
|
|
105
|
+
const contract = new ethers_1.ethers.Contract(config.migrationRegistryAddress, MIGRATION_REGISTRY_ABI, provider);
|
|
106
|
+
const lineage = await contract.getLineage(address);
|
|
107
|
+
if (lineage.length === 0) {
|
|
108
|
+
const payload = { address, lineage: [], migrations: 0 };
|
|
109
|
+
if (opts.json)
|
|
110
|
+
return console.log(JSON.stringify(payload, null, 2));
|
|
111
|
+
console.log(`address=${address}`);
|
|
112
|
+
console.log(` no migration history`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const entries = [];
|
|
116
|
+
for (let i = 0; i < lineage.length - 1; i++) {
|
|
117
|
+
const from = lineage[i];
|
|
118
|
+
const to = lineage[i + 1];
|
|
119
|
+
let timestamp = null;
|
|
120
|
+
let scoreAtMigration = null;
|
|
121
|
+
let decayBps = null;
|
|
122
|
+
try {
|
|
123
|
+
const filter = contract.filters.MigrationRegistered(from, to);
|
|
124
|
+
const events = await contract.queryFilter(filter);
|
|
125
|
+
if (events.length > 0) {
|
|
126
|
+
const ev = events[0];
|
|
127
|
+
const block = await provider.getBlock(ev.blockNumber);
|
|
128
|
+
timestamp = block ? new Date(block.timestamp * 1000).toISOString() : null;
|
|
129
|
+
scoreAtMigration = ev.args[3]?.toString() ?? null;
|
|
130
|
+
decayBps = ev.args[4]?.toString() ?? null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// event query not critical — continue without timestamps
|
|
135
|
+
}
|
|
136
|
+
entries.push({ step: i + 1, from, to, timestamp, scoreAtMigration, decayBps });
|
|
137
|
+
}
|
|
138
|
+
const payload = {
|
|
139
|
+
address,
|
|
140
|
+
lineage,
|
|
141
|
+
migrations: entries.length,
|
|
142
|
+
history: entries,
|
|
143
|
+
};
|
|
144
|
+
if (opts.json)
|
|
145
|
+
return console.log(JSON.stringify(payload, null, 2));
|
|
146
|
+
console.log(`address=${address}`);
|
|
147
|
+
console.log(` lineage depth: ${lineage.length} wallet${lineage.length !== 1 ? "s" : ""}`);
|
|
148
|
+
console.log(` migrations: ${entries.length}`);
|
|
149
|
+
console.log();
|
|
150
|
+
lineage.forEach((addr, i) => {
|
|
151
|
+
const label = i === 0 ? " (origin)" : i === lineage.length - 1 ? " (current)" : "";
|
|
152
|
+
console.log(` [${i}] ${addr}${label}`);
|
|
153
|
+
if (i < entries.length) {
|
|
154
|
+
const e = entries[i];
|
|
155
|
+
if (e.timestamp)
|
|
156
|
+
console.log(` migrated: ${e.timestamp}`);
|
|
157
|
+
if (e.scoreAtMigration)
|
|
158
|
+
console.log(` score at migration: ${e.scoreAtMigration} (decay: ${Number(e.decayBps) / 100}%)`);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"negotiate.d.ts","sourceRoot":"","sources":["../../src/commands/negotiate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6PhE"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerNegotiateCommands = registerNegotiateCommands;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const sdk_1 = require("@arc402/sdk");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const client_1 = require("../client");
|
|
8
|
+
const hash_1 = require("../utils/hash");
|
|
9
|
+
const sessionManager = new sdk_1.SessionManager();
|
|
10
|
+
function registerNegotiateCommands(program) {
|
|
11
|
+
const negotiate = program
|
|
12
|
+
.command("negotiate")
|
|
13
|
+
.description("Signed agent-to-agent negotiation. Every message is authenticated, " +
|
|
14
|
+
"sessions are tracked locally, transcripts are hashed and committed on-chain. " +
|
|
15
|
+
"This is the secure communication layer — not just payload generation.");
|
|
16
|
+
// Session management — nest list/show under a single 'session' subcommand
|
|
17
|
+
const session = negotiate
|
|
18
|
+
.command("session")
|
|
19
|
+
.description("Manage local negotiation sessions");
|
|
20
|
+
session
|
|
21
|
+
.command("list")
|
|
22
|
+
.description("List all negotiation sessions")
|
|
23
|
+
.option("--json", "Machine-parseable output")
|
|
24
|
+
.action((opts) => {
|
|
25
|
+
const sessions = sessionManager.list();
|
|
26
|
+
if (opts.json) {
|
|
27
|
+
console.log(JSON.stringify(sessions));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
sessions.forEach(s => {
|
|
31
|
+
console.log(`${s.sessionId.slice(0, 10)}... ${s.state.padEnd(10)} ${s.initiator} ↔ ${s.responder} msgs:${s.messages.length}`);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
session
|
|
36
|
+
.command("show <sessionId>")
|
|
37
|
+
.description("Show full session including message history and transcript hash")
|
|
38
|
+
.option("--json", "Machine-parseable output")
|
|
39
|
+
.action((sessionId, opts) => {
|
|
40
|
+
const sess = sessionManager.load(sessionId);
|
|
41
|
+
if (opts.json) {
|
|
42
|
+
console.log(JSON.stringify(sess));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(`Session: ${sess.sessionId}`);
|
|
46
|
+
console.log(`State: ${sess.state}`);
|
|
47
|
+
console.log(`Parties: ${sess.initiator} ↔ ${sess.responder}`);
|
|
48
|
+
console.log(`Messages: ${sess.messages.length}`);
|
|
49
|
+
if (sess.transcriptHash)
|
|
50
|
+
console.log(`Transcript hash: ${sess.transcriptHash}`);
|
|
51
|
+
if (sess.onChainAgreementId)
|
|
52
|
+
console.log(`On-chain agreement: ${sess.onChainAgreementId}`);
|
|
53
|
+
sess.messages.forEach((m, i) => console.log(` ${i + 1}. ${m.type} from ${m.from.slice(0, 8)}...`));
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Signed propose (starts a new session)
|
|
57
|
+
negotiate
|
|
58
|
+
.command("propose")
|
|
59
|
+
.description("Send a signed PROPOSE. Creates a new negotiation session.")
|
|
60
|
+
.requiredOption("--to <address>")
|
|
61
|
+
.requiredOption("--service-type <type>")
|
|
62
|
+
.requiredOption("--price <amountWei>")
|
|
63
|
+
.option("--token <token>", "Token address", ethers_1.ethers.ZeroAddress)
|
|
64
|
+
.requiredOption("--deadline <iso>")
|
|
65
|
+
.requiredOption("--spec <text>")
|
|
66
|
+
.option("--spec-file <path>")
|
|
67
|
+
.option("--expires-in <seconds>", "Proposal TTL in seconds", "3600")
|
|
68
|
+
.option("--json", "Machine-parseable output")
|
|
69
|
+
.action(async (opts) => {
|
|
70
|
+
const config = (0, config_1.loadConfig)();
|
|
71
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
72
|
+
const myAddress = await signer.getAddress();
|
|
73
|
+
const specHash = opts.specFile ? (0, hash_1.hashFile)(opts.specFile) : (0, hash_1.hashString)(opts.spec);
|
|
74
|
+
const now = Math.floor(Date.now() / 1000);
|
|
75
|
+
const session = sessionManager.createSession(myAddress, opts.to);
|
|
76
|
+
const proposal = await (0, sdk_1.createSignedProposal)({
|
|
77
|
+
from: myAddress,
|
|
78
|
+
to: opts.to,
|
|
79
|
+
serviceType: opts.serviceType,
|
|
80
|
+
price: opts.price,
|
|
81
|
+
token: opts.token,
|
|
82
|
+
deadline: opts.deadline,
|
|
83
|
+
spec: opts.spec,
|
|
84
|
+
specHash,
|
|
85
|
+
expiresAt: now + parseInt(opts.expiresIn),
|
|
86
|
+
protocolVersion: "1.0.0",
|
|
87
|
+
}, signer);
|
|
88
|
+
sessionManager.addMessage(session.sessionId, proposal);
|
|
89
|
+
if (opts.json) {
|
|
90
|
+
console.log(JSON.stringify({ sessionId: session.sessionId, message: proposal }));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.log(`Session started: ${session.sessionId}`);
|
|
94
|
+
console.log(`Signed PROPOSE:`);
|
|
95
|
+
console.log(JSON.stringify(proposal, null, 2));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
// Counter
|
|
99
|
+
negotiate
|
|
100
|
+
.command("counter <sessionId>")
|
|
101
|
+
.description("Send a signed COUNTER within an existing session.")
|
|
102
|
+
.requiredOption("--justification <text>")
|
|
103
|
+
.option("--price <amountWei>")
|
|
104
|
+
.option("--deadline <iso>")
|
|
105
|
+
.option("--json", "Machine-parseable output")
|
|
106
|
+
.action(async (sessionId, opts) => {
|
|
107
|
+
const config = (0, config_1.loadConfig)();
|
|
108
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
109
|
+
const myAddress = await signer.getAddress();
|
|
110
|
+
const session = sessionManager.load(sessionId);
|
|
111
|
+
const lastMessage = session.messages[session.messages.length - 1];
|
|
112
|
+
const refNonce = "nonce" in lastMessage ? lastMessage.nonce : lastMessage.refNonce;
|
|
113
|
+
const counter = await (0, sdk_1.createSignedCounter)({
|
|
114
|
+
from: myAddress,
|
|
115
|
+
to: lastMessage.from === myAddress ? lastMessage.to : lastMessage.from,
|
|
116
|
+
refNonce,
|
|
117
|
+
justification: opts.justification,
|
|
118
|
+
price: opts.price,
|
|
119
|
+
deadline: opts.deadline,
|
|
120
|
+
}, signer);
|
|
121
|
+
sessionManager.addMessage(sessionId, counter);
|
|
122
|
+
if (opts.json) {
|
|
123
|
+
console.log(JSON.stringify(counter));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
console.log(`Signed COUNTER added to session ${sessionId.slice(0, 10)}...`);
|
|
127
|
+
console.log(JSON.stringify(counter, null, 2));
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
// Accept — closes session, computes transcript hash
|
|
131
|
+
negotiate
|
|
132
|
+
.command("accept <sessionId>")
|
|
133
|
+
.description("Accept terms. Closes the session and computes transcript hash.")
|
|
134
|
+
.requiredOption("--price <amountWei>")
|
|
135
|
+
.requiredOption("--deadline <iso>")
|
|
136
|
+
.option("--record", "Commit transcript hash on-chain alongside propose()")
|
|
137
|
+
.option("--json", "Machine-parseable output")
|
|
138
|
+
.action(async (sessionId, opts) => {
|
|
139
|
+
const config = (0, config_1.loadConfig)();
|
|
140
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
141
|
+
const myAddress = await signer.getAddress();
|
|
142
|
+
const session = sessionManager.load(sessionId);
|
|
143
|
+
const lastMessage = session.messages[session.messages.length - 1];
|
|
144
|
+
const refNonce = "nonce" in lastMessage ? lastMessage.nonce : lastMessage.refNonce;
|
|
145
|
+
const accept = await (0, sdk_1.createSignedAccept)({
|
|
146
|
+
from: myAddress,
|
|
147
|
+
to: lastMessage.from === myAddress ? lastMessage.to : lastMessage.from,
|
|
148
|
+
refNonce,
|
|
149
|
+
agreedPrice: opts.price,
|
|
150
|
+
agreedDeadline: opts.deadline,
|
|
151
|
+
}, signer);
|
|
152
|
+
sessionManager.addMessage(sessionId, accept);
|
|
153
|
+
const updatedSession = sessionManager.load(sessionId);
|
|
154
|
+
if (opts.json) {
|
|
155
|
+
console.log(JSON.stringify({
|
|
156
|
+
sessionId,
|
|
157
|
+
transcriptHash: updatedSession.transcriptHash,
|
|
158
|
+
message: accept,
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
console.log(`✓ Session ${sessionId.slice(0, 10)}... ACCEPTED`);
|
|
163
|
+
console.log(`✓ Transcript hash: ${updatedSession.transcriptHash}`);
|
|
164
|
+
if (opts.record) {
|
|
165
|
+
console.log(`\nTranscript hash is ready to commit on-chain.`);
|
|
166
|
+
console.log(`Run: arc402 hire --session ${sessionId} to propose() and record the transcript hash.`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
// Reject
|
|
171
|
+
negotiate
|
|
172
|
+
.command("reject <sessionId>")
|
|
173
|
+
.description("Reject and close session.")
|
|
174
|
+
.requiredOption("--reason <text>")
|
|
175
|
+
.option("--json", "Machine-parseable output")
|
|
176
|
+
.action(async (sessionId, opts) => {
|
|
177
|
+
const config = (0, config_1.loadConfig)();
|
|
178
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
179
|
+
const myAddress = await signer.getAddress();
|
|
180
|
+
const session = sessionManager.load(sessionId);
|
|
181
|
+
const lastMessage = session.messages[session.messages.length - 1];
|
|
182
|
+
const refNonce = "nonce" in lastMessage ? lastMessage.nonce : lastMessage.refNonce;
|
|
183
|
+
const reject = await (0, sdk_1.createSignedReject)({
|
|
184
|
+
from: myAddress,
|
|
185
|
+
to: lastMessage.from === myAddress ? lastMessage.to : lastMessage.from,
|
|
186
|
+
reason: opts.reason,
|
|
187
|
+
refNonce,
|
|
188
|
+
}, signer);
|
|
189
|
+
sessionManager.addMessage(sessionId, reject);
|
|
190
|
+
if (opts.json) {
|
|
191
|
+
console.log(JSON.stringify(reject));
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
console.log(`✗ Session ${sessionId.slice(0, 10)}... REJECTED`);
|
|
195
|
+
console.log(`Reason: ${opts.reason}`);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
// Verify an incoming message
|
|
199
|
+
negotiate
|
|
200
|
+
.command("verify")
|
|
201
|
+
.description("Verify an incoming signed negotiation message against AgentRegistry.")
|
|
202
|
+
.requiredOption("--message <json>", "Raw JSON string or @file.json")
|
|
203
|
+
.option("--json", "Machine-parseable output")
|
|
204
|
+
.action(async (opts) => {
|
|
205
|
+
const config = (0, config_1.loadConfig)();
|
|
206
|
+
if (!config.agentRegistryAddress)
|
|
207
|
+
throw new Error("agentRegistryAddress not in config");
|
|
208
|
+
const { provider } = await (0, client_1.getClient)(config);
|
|
209
|
+
const guard = new sdk_1.NegotiationGuard({ agentRegistryAddress: config.agentRegistryAddress, runner: provider });
|
|
210
|
+
const rawJson = opts.message.startsWith("@")
|
|
211
|
+
? require("fs").readFileSync(opts.message.slice(1), "utf8")
|
|
212
|
+
: opts.message;
|
|
213
|
+
const result = await guard.verify(rawJson);
|
|
214
|
+
if (opts.json) {
|
|
215
|
+
console.log(JSON.stringify(result));
|
|
216
|
+
}
|
|
217
|
+
else if (result.valid) {
|
|
218
|
+
console.log(`✓ Valid — signer: ${result.recoveredSigner}`);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
console.error(`✗ Invalid — ${result.error}`);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
// Transcript subcommand
|
|
226
|
+
const transcript = negotiate.command("transcript").description("Transcript management for closed negotiation sessions");
|
|
227
|
+
transcript
|
|
228
|
+
.command("show <sessionId>")
|
|
229
|
+
.description("Show the transcript hash for a completed session")
|
|
230
|
+
.option("--json", "Machine-parseable output")
|
|
231
|
+
.action((sessionId, opts) => {
|
|
232
|
+
const session = sessionManager.load(sessionId);
|
|
233
|
+
if (!session.transcriptHash) {
|
|
234
|
+
console.error("Session not yet closed — no transcript hash");
|
|
235
|
+
process.exit(1);
|
|
236
|
+
}
|
|
237
|
+
if (opts.json) {
|
|
238
|
+
console.log(JSON.stringify({ sessionId, transcriptHash: session.transcriptHash, messageCount: session.messages.length }));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
console.log(`Transcript hash: ${session.transcriptHash}`);
|
|
242
|
+
console.log(`Messages: ${session.messages.length}`);
|
|
243
|
+
console.log(`State: ${session.state}`);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=negotiate.js.map
|