@heyanon-arp/cli 0.0.24 → 0.0.26
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/dist/cli.js +811 -705
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -322,6 +322,9 @@ var init_api = __esm({
|
|
|
322
322
|
async getReputation(did) {
|
|
323
323
|
return this.get(`/v1/agents/${encodeURIComponent(did)}/reputation`);
|
|
324
324
|
}
|
|
325
|
+
async getStats(did) {
|
|
326
|
+
return this.get(`/v1/agents/${encodeURIComponent(did)}/stats`);
|
|
327
|
+
}
|
|
325
328
|
/**
|
|
326
329
|
* Public `GET /v1/discovery/search`. Reputation-ranked agent search
|
|
327
330
|
* with creator / liveness / accepted-asset filters. No auth.
|
|
@@ -733,7 +736,7 @@ var import_commander = require("commander");
|
|
|
733
736
|
// package.json
|
|
734
737
|
var package_default = {
|
|
735
738
|
name: "@heyanon-arp/cli",
|
|
736
|
-
version: "0.0.
|
|
739
|
+
version: "0.0.26",
|
|
737
740
|
description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
|
|
738
741
|
license: "MIT",
|
|
739
742
|
keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
|
|
@@ -822,6 +825,14 @@ function optionPlacementHelpNote() {
|
|
|
822
825
|
` ${import_chalk.default.cyan("heyarp <command> [options]")} ${import_chalk.default.dim("e.g. heyarp relationships --json --from-did did:arp:\u2026")}`
|
|
823
826
|
].join("\n");
|
|
824
827
|
}
|
|
828
|
+
var CliError = class extends Error {
|
|
829
|
+
constructor(code, message, details) {
|
|
830
|
+
super(message);
|
|
831
|
+
this.code = code;
|
|
832
|
+
this.details = details;
|
|
833
|
+
this.name = "CliError";
|
|
834
|
+
}
|
|
835
|
+
};
|
|
825
836
|
function toCliErrorJson(err, includeStack = false) {
|
|
826
837
|
const { ApiError: ApiError2 } = (init_api(), __toCommonJS(api_exports));
|
|
827
838
|
if (err instanceof ApiError2) {
|
|
@@ -830,6 +841,12 @@ function toCliErrorJson(err, includeStack = false) {
|
|
|
830
841
|
if (details !== void 0) out2.details = details;
|
|
831
842
|
return out2;
|
|
832
843
|
}
|
|
844
|
+
if (err instanceof CliError) {
|
|
845
|
+
const out2 = { code: err.code, message: err.message };
|
|
846
|
+
if (err.details) out2.details = err.details;
|
|
847
|
+
if (includeStack && err.stack) out2.details = { ...out2.details, stack: err.stack };
|
|
848
|
+
return out2;
|
|
849
|
+
}
|
|
833
850
|
if (err instanceof Error && err.code === "OUTBOUND_BLOCKED") {
|
|
834
851
|
const e = err;
|
|
835
852
|
const reasons = e.verdict?.reasons ?? e.reasons;
|
|
@@ -1281,7 +1298,9 @@ ${verb}.`));
|
|
|
1281
1298
|
|
|
1282
1299
|
// src/commands/agents.ts
|
|
1283
1300
|
function registerAgentsCommand(root) {
|
|
1284
|
-
const agents = root.command("agents").description(
|
|
1301
|
+
const agents = root.command("agents").description(
|
|
1302
|
+
"Search published agents (reputation-ranked) \u2014 ONLINE-only by default (seen within the liveness window); --all includes offline. Filter by tag / text / creator account / accepted asset."
|
|
1303
|
+
).option("--server <url>", "Override ARP server base URL").option("--tag <s>", "Filter by capability tag \u2014 repeatable; AND-semantics across tags", accumulate2, []).option("--query <s>", "Full-text search over name + description").option("--account-id <wallet>", "Filter to a creator account (owner wallet, base58)").option("--accepts <asset>", "Filter to agents that accept this asset \u2014 shorthand (SOL:solana-devnet) or CAIP-19. Matches accept-anything agents too.").option("--all", "Include offline agents too \u2014 by default only agents seen within the ~5-min liveness window are listed", false).option("--sort <mode>", "reputation (default) | recent | created", "reputation").option("--page <n>", "Zero-based page index (reputation/recent sorts)", "0").option("--after <id>", "Cursor for --sort created: the previous page's last `id`").option("--limit <n>", "Max rows to return (1..100)", "20").option(
|
|
1285
1304
|
"--verbose",
|
|
1286
1305
|
'After the one-line summaries, print a framed "Full agent payloads (N rows)" block containing the JSON array of all rows (with owner-string sanitisation for terminal safety)',
|
|
1287
1306
|
false
|
|
@@ -1318,7 +1337,7 @@ async function runAgents(opts) {
|
|
|
1318
1337
|
if (opts.query) query.q = opts.query;
|
|
1319
1338
|
if (opts.accountId) query.accountId = opts.accountId;
|
|
1320
1339
|
if (opts.accepts) query.accepts = resolveAcceptsAsset(opts.accepts);
|
|
1321
|
-
if (opts.
|
|
1340
|
+
if (!opts.all) query.online = true;
|
|
1322
1341
|
if (sort === import_sdk3.DiscoverySorts.CREATED) {
|
|
1323
1342
|
if (opts.after) query.after = opts.after;
|
|
1324
1343
|
} else {
|
|
@@ -1705,8 +1724,8 @@ function unknownKey(key) {
|
|
|
1705
1724
|
|
|
1706
1725
|
// src/commands/delegation.ts
|
|
1707
1726
|
var import_node_fs4 = require("fs");
|
|
1708
|
-
var
|
|
1709
|
-
var
|
|
1727
|
+
var import_sdk13 = require("@heyanon-arp/sdk");
|
|
1728
|
+
var import_chalk11 = __toESM(require("chalk"));
|
|
1710
1729
|
init_api();
|
|
1711
1730
|
|
|
1712
1731
|
// src/id-format.ts
|
|
@@ -1744,30 +1763,181 @@ function requireUuid(cmdName, raw, label) {
|
|
|
1744
1763
|
throw new Error(hint ? `${base} \u2014 ${hint}` : base);
|
|
1745
1764
|
}
|
|
1746
1765
|
|
|
1747
|
-
// src/
|
|
1766
|
+
// src/recipient-liveness.ts
|
|
1767
|
+
var import_chalk8 = __toESM(require("chalk"));
|
|
1768
|
+
|
|
1769
|
+
// src/commands/doctor.ts
|
|
1748
1770
|
var import_sdk7 = require("@heyanon-arp/sdk");
|
|
1749
1771
|
var import_chalk7 = __toESM(require("chalk"));
|
|
1750
1772
|
init_api();
|
|
1773
|
+
function registerDoctorCommand(root) {
|
|
1774
|
+
root.command("doctor").description("Liveness probe for a counterparty: resolve DID document + read protocol activity. No auth.").argument("<did>", "did:arp:<base58btc> of the agent to probe").option("--server <url>", "Override ARP server base URL").option("--json", "Machine-readable: single JSON object on stdout. Pipe-safe.", false).action(async (did, opts) => {
|
|
1775
|
+
await runDoctor(did, opts);
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
var LISTENING_THRESHOLD_SECONDS = 15 * 60;
|
|
1779
|
+
async function runDoctor(did, opts) {
|
|
1780
|
+
if (!(0, import_sdk7.isValidDid)(did)) {
|
|
1781
|
+
throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
|
|
1782
|
+
}
|
|
1783
|
+
const api = new ArpApiClient(opts.server);
|
|
1784
|
+
const result = await probe(api, did);
|
|
1785
|
+
if (opts.json) {
|
|
1786
|
+
console.log(JSON.stringify(result));
|
|
1787
|
+
} else {
|
|
1788
|
+
console.log(formatDoctorReport(result));
|
|
1789
|
+
}
|
|
1790
|
+
if (result.verdict !== "LISTENING") {
|
|
1791
|
+
process.exitCode = 1;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
async function probe(api, did) {
|
|
1795
|
+
const base = {
|
|
1796
|
+
did,
|
|
1797
|
+
server: api.serverUrl,
|
|
1798
|
+
didDocument: { found: false },
|
|
1799
|
+
verdict: "UNKNOWN",
|
|
1800
|
+
reason: ""
|
|
1801
|
+
};
|
|
1802
|
+
let doc;
|
|
1803
|
+
try {
|
|
1804
|
+
doc = await api.getDidDocument(did);
|
|
1805
|
+
} catch (err) {
|
|
1806
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
1807
|
+
return { ...base, verdict: "UNKNOWN", reason: "DID not registered on this server" };
|
|
1808
|
+
}
|
|
1809
|
+
return { ...base, verdict: "UNKNOWN", reason: `DID document fetch failed: ${err.message}` };
|
|
1810
|
+
}
|
|
1811
|
+
base.didDocument = { found: true, registeredAt: doc.metadata?.registered_at };
|
|
1812
|
+
let activity;
|
|
1813
|
+
try {
|
|
1814
|
+
const summary = await api.getActivitySummary(did);
|
|
1815
|
+
const asOfMs = new Date(summary.asOf).getTime();
|
|
1816
|
+
const lastMs = summary.lastEventAt ? new Date(summary.lastEventAt).getTime() : null;
|
|
1817
|
+
const ageSeconds = lastMs !== null ? Math.max(0, Math.floor((asOfMs - lastMs) / 1e3)) : null;
|
|
1818
|
+
const seenMs = summary.lastSeenAt ? new Date(summary.lastSeenAt).getTime() : null;
|
|
1819
|
+
const seenAgeSeconds = seenMs !== null ? Math.max(0, Math.floor((asOfMs - seenMs) / 1e3)) : null;
|
|
1820
|
+
activity = {
|
|
1821
|
+
lastEventAt: summary.lastEventAt,
|
|
1822
|
+
asOf: summary.asOf,
|
|
1823
|
+
ageSeconds,
|
|
1824
|
+
lastSeenAt: summary.lastSeenAt ?? null,
|
|
1825
|
+
seenAgeSeconds,
|
|
1826
|
+
inboxStreamActive: summary.inboxStreamActive
|
|
1827
|
+
};
|
|
1828
|
+
} catch {
|
|
1829
|
+
return { ...base, verdict: "UNKNOWN", reason: "DID resolves but the server does not expose an activity summary \u2014 cannot assess liveness" };
|
|
1830
|
+
}
|
|
1831
|
+
const recentlyActive = activity.ageSeconds !== null && activity.ageSeconds !== void 0 && activity.ageSeconds <= LISTENING_THRESHOLD_SECONDS;
|
|
1832
|
+
const recentlySeen = activity.seenAgeSeconds !== null && activity.seenAgeSeconds !== void 0 && activity.seenAgeSeconds <= LISTENING_THRESHOLD_SECONDS;
|
|
1833
|
+
const inboxStreamActive = activity.inboxStreamActive === true;
|
|
1834
|
+
const result = { ...base, activity };
|
|
1835
|
+
if (inboxStreamActive) {
|
|
1836
|
+
return {
|
|
1837
|
+
...result,
|
|
1838
|
+
verdict: "LISTENING",
|
|
1839
|
+
reason: "inbox-stream attached (active SSE subscription on the central server) \u2014 protocol-reachable; worker is actively waiting for envelopes"
|
|
1840
|
+
};
|
|
1841
|
+
}
|
|
1842
|
+
if (recentlySeen) {
|
|
1843
|
+
const seenStr = activity.seenAgeSeconds !== void 0 && activity.seenAgeSeconds !== null ? `${activity.seenAgeSeconds}s ago` : "recently";
|
|
1844
|
+
return {
|
|
1845
|
+
...result,
|
|
1846
|
+
verdict: "LISTENING",
|
|
1847
|
+
reason: `recently seen (signed API request ${seenStr}) \u2014 agent is polling the server (cron-mode worker)`
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
if (recentlyActive) {
|
|
1851
|
+
const ageStr = activity.ageSeconds !== void 0 && activity.ageSeconds !== null ? `${activity.ageSeconds}s ago` : "recently";
|
|
1852
|
+
return {
|
|
1853
|
+
...result,
|
|
1854
|
+
verdict: "LISTENING",
|
|
1855
|
+
reason: `inbox-active (last event ${ageStr}) \u2014 protocol-reachable via the central ARP server`
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
const ageNote = activity.lastEventAt === null ? "no events ever" : `last event ${activity.ageSeconds}s ago`;
|
|
1859
|
+
const seenNote = activity.lastSeenAt === null || activity.lastSeenAt === void 0 ? "never seen polling" : `last seen ${activity.seenAgeSeconds}s ago`;
|
|
1860
|
+
return { ...result, verdict: "DORMANT", reason: `no open inbox stream, ${seenNote}, and ${ageNote} \u2014 agent appears idle (cross-check before relying on it)` };
|
|
1861
|
+
}
|
|
1862
|
+
function formatDoctorReport(r) {
|
|
1863
|
+
const lines = [];
|
|
1864
|
+
lines.push(`${import_chalk7.default.dim("Server:")} ${r.server}`);
|
|
1865
|
+
lines.push(`${import_chalk7.default.dim("Target DID:")} ${r.did}`);
|
|
1866
|
+
if (!r.didDocument.found) {
|
|
1867
|
+
lines.push(`${import_chalk7.default.dim("DID doc:")} ${import_chalk7.default.red("\u2717")} not found`);
|
|
1868
|
+
} else {
|
|
1869
|
+
const registered = r.didDocument.registeredAt ? ` (registered ${r.didDocument.registeredAt})` : "";
|
|
1870
|
+
lines.push(`${import_chalk7.default.dim("DID doc:")} ${import_chalk7.default.green("\u2713")} resolved${registered}`);
|
|
1871
|
+
}
|
|
1872
|
+
if (r.activity) {
|
|
1873
|
+
if (r.activity.lastEventAt === null) {
|
|
1874
|
+
lines.push(`${import_chalk7.default.dim("Activity:")} ${import_chalk7.default.dim("(no events ever \u2014 fresh agent)")}`);
|
|
1875
|
+
} else {
|
|
1876
|
+
const ageMin = r.activity.ageSeconds !== null ? Math.floor(r.activity.ageSeconds / 60) : null;
|
|
1877
|
+
const ageStr = ageMin !== null && ageMin > 0 ? `${ageMin}m ago` : `${r.activity.ageSeconds}s ago`;
|
|
1878
|
+
lines.push(`${import_chalk7.default.dim("Activity:")} last event ${ageStr} (${r.activity.lastEventAt})`);
|
|
1879
|
+
}
|
|
1880
|
+
if (r.activity.lastSeenAt !== null && r.activity.lastSeenAt !== void 0) {
|
|
1881
|
+
const seenMin = r.activity.seenAgeSeconds !== null && r.activity.seenAgeSeconds !== void 0 ? Math.floor(r.activity.seenAgeSeconds / 60) : null;
|
|
1882
|
+
const seenStr = seenMin !== null && seenMin > 0 ? `${seenMin}m ago` : `${r.activity.seenAgeSeconds}s ago`;
|
|
1883
|
+
lines.push(`${import_chalk7.default.dim("Last seen:")} signed request ${seenStr} (${r.activity.lastSeenAt})`);
|
|
1884
|
+
}
|
|
1885
|
+
if (r.activity.inboxStreamActive === true) {
|
|
1886
|
+
lines.push(`${import_chalk7.default.dim("Inbox SSE:")} ${import_chalk7.default.green("\u2713")} active subscription on the central server`);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
const verdictColor = r.verdict === "LISTENING" ? import_chalk7.default.green : r.verdict === "DORMANT" ? import_chalk7.default.red : import_chalk7.default.yellow;
|
|
1890
|
+
lines.push("");
|
|
1891
|
+
lines.push(`${import_chalk7.default.bold("Verdict:")} ${verdictColor(r.verdict)} \u2014 ${r.reason}`);
|
|
1892
|
+
return lines.join("\n");
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
// src/recipient-liveness.ts
|
|
1896
|
+
async function guardRecipientReachable(api, recipientDid, opts) {
|
|
1897
|
+
let verdict;
|
|
1898
|
+
let reason;
|
|
1899
|
+
try {
|
|
1900
|
+
const result = await probe(api, recipientDid);
|
|
1901
|
+
verdict = result.verdict;
|
|
1902
|
+
reason = result.reason;
|
|
1903
|
+
} catch {
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (verdict === "LISTENING") return;
|
|
1907
|
+
if (verdict === "UNKNOWN" && !opts.requireOnline) return;
|
|
1908
|
+
const state = verdict === "DORMANT" ? "appears offline (idle)" : "has undetermined liveness";
|
|
1909
|
+
const detail = `recipient ${recipientDid} ${state} \u2014 ${reason}`;
|
|
1910
|
+
if (opts.requireOnline) {
|
|
1911
|
+
throw new CliError("CLI_RECIPIENT_OFFLINE", `${detail}. Aborted because --require-online is set.`, { recipientDid, verdict });
|
|
1912
|
+
}
|
|
1913
|
+
console.error(import_chalk8.default.yellow(`\u26A0 ${detail}`));
|
|
1914
|
+
console.error(import_chalk8.default.dim(" Sending anyway \u2014 it will wait in their inbox. Pass --require-online to abort instead."));
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
// src/resolve-recipient.ts
|
|
1918
|
+
var import_sdk8 = require("@heyanon-arp/sdk");
|
|
1919
|
+
var import_chalk9 = __toESM(require("chalk"));
|
|
1920
|
+
init_api();
|
|
1751
1921
|
async function resolveRecipient(serverOverride, cmdName, input, opts = {}) {
|
|
1752
1922
|
if (input.startsWith("did:arp:")) {
|
|
1753
|
-
if (!(0,
|
|
1923
|
+
if (!(0, import_sdk8.isValidDid)(input)) {
|
|
1754
1924
|
throw new Error(`${cmdName}: '${input}' starts with did:arp: but is not a valid DID (base58btc-encoded 32-byte Ed25519 pubkey).`);
|
|
1755
1925
|
}
|
|
1756
1926
|
return input;
|
|
1757
1927
|
}
|
|
1758
|
-
const name = (0,
|
|
1759
|
-
if (!(0,
|
|
1928
|
+
const name = (0, import_sdk8.normalizeName)(input);
|
|
1929
|
+
if (!(0, import_sdk8.isValidAgentName)(name)) {
|
|
1760
1930
|
throw new Error(`${cmdName}: '${input}' is neither a DID (did:arp:...) nor a valid agent name (lowercase a-z0-9_, 3-32 chars).`);
|
|
1761
1931
|
}
|
|
1762
1932
|
const api = new ArpApiClient(serverOverride);
|
|
1763
1933
|
const profile = await api.discoverByName(name);
|
|
1764
|
-
warn(opts.json,
|
|
1934
|
+
warn(opts.json, import_chalk9.default.dim(`Resolved ${import_chalk9.default.cyan(name)} \u2192 ${profile.did}${profile.description ? ` (${profile.description})` : ""}`));
|
|
1765
1935
|
return profile.did;
|
|
1766
1936
|
}
|
|
1767
1937
|
|
|
1768
1938
|
// src/commands/status.ts
|
|
1769
|
-
var
|
|
1770
|
-
var
|
|
1939
|
+
var import_sdk9 = require("@heyanon-arp/sdk");
|
|
1940
|
+
var import_chalk10 = __toESM(require("chalk"));
|
|
1771
1941
|
init_api();
|
|
1772
1942
|
var UNTIL_PHASES = [
|
|
1773
1943
|
"delegation.offered",
|
|
@@ -1822,9 +1992,9 @@ async function runStatus(relationshipId, opts) {
|
|
|
1822
1992
|
const api = new ArpApiClient(opts.server);
|
|
1823
1993
|
const sender = resolveSenderAgent("status", opts.server, opts.fromDid, opts.from);
|
|
1824
1994
|
if (!opts.json) {
|
|
1825
|
-
console.log(
|
|
1826
|
-
console.log(
|
|
1827
|
-
console.log(
|
|
1995
|
+
console.log(import_chalk10.default.dim(`Server: ${api.serverUrl}`));
|
|
1996
|
+
console.log(import_chalk10.default.dim(`Signer: ${sender.did}`));
|
|
1997
|
+
console.log(import_chalk10.default.dim(`Relationship: ${relationshipId}`));
|
|
1828
1998
|
}
|
|
1829
1999
|
const signer = makeSigner(sender);
|
|
1830
2000
|
if (!opts.wait) {
|
|
@@ -1856,7 +2026,7 @@ async function runStatus(relationshipId, opts) {
|
|
|
1856
2026
|
async function awaitFsmTransitionAfterAction(input) {
|
|
1857
2027
|
const { api, signerDid, signer, relationshipId, untilPhase, waitIntervalSec, waitTimeoutSec, waitVerbose, json } = input;
|
|
1858
2028
|
if (!json) {
|
|
1859
|
-
console.log(
|
|
2029
|
+
console.log(import_chalk10.default.dim(`
|
|
1860
2030
|
[--wait-until ${untilPhase}] polling relationship ${relationshipId} (interval=${waitIntervalSec}s timeout=${waitTimeoutSec}s)`));
|
|
1861
2031
|
}
|
|
1862
2032
|
const outcome = await runWaitLoop({
|
|
@@ -1873,13 +2043,13 @@ async function awaitFsmTransitionAfterAction(input) {
|
|
|
1873
2043
|
}
|
|
1874
2044
|
}
|
|
1875
2045
|
async function runWaitLoop(opts) {
|
|
1876
|
-
const isTerminal = (s) => s.cycleComplete || s.relationshipState ===
|
|
2046
|
+
const isTerminal = (s) => s.cycleComplete || s.relationshipState === import_sdk9.RelationshipStates.CLOSED || s.relationshipState === "not_found";
|
|
1877
2047
|
const isActionable = (s) => {
|
|
1878
2048
|
if (s.nextActionOwner === "me") {
|
|
1879
2049
|
if (s.relationshipState === "unknown") return false;
|
|
1880
2050
|
return true;
|
|
1881
2051
|
}
|
|
1882
|
-
if (s.nextActionOwner === "either" && s.relationshipState ===
|
|
2052
|
+
if (s.nextActionOwner === "either" && s.relationshipState === import_sdk9.RelationshipStates.ACTIVE) {
|
|
1883
2053
|
return true;
|
|
1884
2054
|
}
|
|
1885
2055
|
return false;
|
|
@@ -1895,7 +2065,7 @@ async function runWaitLoop(opts) {
|
|
|
1895
2065
|
}
|
|
1896
2066
|
if (isUntilReached !== null && isUntilReached(initial)) {
|
|
1897
2067
|
if (opts.json) opts.log(JSON.stringify(initial));
|
|
1898
|
-
else opts.log(
|
|
2068
|
+
else opts.log(import_chalk10.default.dim(`
|
|
1899
2069
|
[--wait] Phase '${opts.until}' already reached \u2014 exiting without polling.`));
|
|
1900
2070
|
return { timedOut: false, last: initial };
|
|
1901
2071
|
}
|
|
@@ -1906,13 +2076,13 @@ async function runWaitLoop(opts) {
|
|
|
1906
2076
|
else {
|
|
1907
2077
|
if (opts.until !== void 0) {
|
|
1908
2078
|
opts.log(
|
|
1909
|
-
|
|
2079
|
+
import_chalk10.default.yellow(
|
|
1910
2080
|
`
|
|
1911
2081
|
[--wait] Terminal state (${initial.relationshipState}, cycleComplete=${initial.cycleComplete}) reached before phase '${opts.until}' \u2014 exiting; phase unreachable.`
|
|
1912
2082
|
)
|
|
1913
2083
|
);
|
|
1914
2084
|
} else {
|
|
1915
|
-
opts.log(
|
|
2085
|
+
opts.log(import_chalk10.default.dim(`
|
|
1916
2086
|
[--wait] Already terminal \u2014 exiting.`));
|
|
1917
2087
|
}
|
|
1918
2088
|
}
|
|
@@ -1920,15 +2090,15 @@ async function runWaitLoop(opts) {
|
|
|
1920
2090
|
}
|
|
1921
2091
|
if (opts.until === void 0 && isActionable(initial)) {
|
|
1922
2092
|
if (opts.json) opts.log(JSON.stringify(initial));
|
|
1923
|
-
else opts.log(
|
|
2093
|
+
else opts.log(import_chalk10.default.dim(`
|
|
1924
2094
|
[--wait] Your turn already (nextActionOwner=${initial.nextActionOwner}) \u2014 exiting without polling.`));
|
|
1925
2095
|
return { timedOut: false, last: initial };
|
|
1926
2096
|
}
|
|
1927
2097
|
if (!opts.json) {
|
|
1928
2098
|
const blockerLabel = opts.until !== void 0 ? `Awaiting phase '${opts.until}'` : initial.nextActionOwner === "counterparty" ? "Counterparty owes the next move" : initial.nextActionOwner === "either" ? "Either side may act" : `Awaiting state change (currently ${initial.relationshipState}, nextActionOwner=${initial.nextActionOwner})`;
|
|
1929
|
-
opts.log(
|
|
2099
|
+
opts.log(import_chalk10.default.dim(`
|
|
1930
2100
|
[--wait] ${blockerLabel}. Polling every ${opts.waitIntervalSec}s, timeout ${opts.waitTimeoutSec}s.`));
|
|
1931
|
-
opts.log(
|
|
2101
|
+
opts.log(import_chalk10.default.dim(`[--wait] Initial hint: ${initial.nextActionHint}`));
|
|
1932
2102
|
}
|
|
1933
2103
|
const startedAt = localNow();
|
|
1934
2104
|
const deadline = startedAt + opts.waitTimeoutSec * 1e3;
|
|
@@ -1948,7 +2118,7 @@ async function runWaitLoop(opts) {
|
|
|
1948
2118
|
} else {
|
|
1949
2119
|
target = `nextActionOwner=${next.nextActionOwner}`;
|
|
1950
2120
|
}
|
|
1951
|
-
opts.log(
|
|
2121
|
+
opts.log(import_chalk10.default.dim(`[--wait tick ${tickIndex}/${maxTicks}] state=${next.relationshipState}, ${formatPhaseSnapshot(next)} (${target})`));
|
|
1952
2122
|
}
|
|
1953
2123
|
if (exitPredicate(next)) {
|
|
1954
2124
|
const phaseReached = isUntilReached !== null ? isUntilReached(next) : false;
|
|
@@ -1958,16 +2128,16 @@ async function runWaitLoop(opts) {
|
|
|
1958
2128
|
opts.log("");
|
|
1959
2129
|
if (opts.until !== void 0) {
|
|
1960
2130
|
if (phaseReached) {
|
|
1961
|
-
opts.log(
|
|
2131
|
+
opts.log(import_chalk10.default.green(`[--wait] Phase '${opts.until}' reached.`));
|
|
1962
2132
|
} else {
|
|
1963
2133
|
opts.log(
|
|
1964
|
-
|
|
2134
|
+
import_chalk10.default.yellow(
|
|
1965
2135
|
`[--wait] Terminal state (${next.relationshipState}, cycleComplete=${next.cycleComplete}) reached before phase '${opts.until}' \u2014 phase unreachable.`
|
|
1966
2136
|
)
|
|
1967
2137
|
);
|
|
1968
2138
|
}
|
|
1969
2139
|
} else {
|
|
1970
|
-
opts.log(
|
|
2140
|
+
opts.log(import_chalk10.default.green(`[--wait] ${isTerminal(next) ? "Cycle terminated" : `Your turn (owner=${next.nextActionOwner})`}.`));
|
|
1971
2141
|
}
|
|
1972
2142
|
opts.log(formatStatusReport(next));
|
|
1973
2143
|
}
|
|
@@ -1980,14 +2150,14 @@ async function runWaitLoop(opts) {
|
|
|
1980
2150
|
} else {
|
|
1981
2151
|
if (opts.until !== void 0) {
|
|
1982
2152
|
opts.log(
|
|
1983
|
-
|
|
2153
|
+
import_chalk10.default.yellow(
|
|
1984
2154
|
`
|
|
1985
2155
|
[--wait] Timed out after ${opts.waitTimeoutSec}s without reaching phase '${opts.until}' (latest state: ${last.relationshipState}, hint: ${last.nextActionHint}).`
|
|
1986
2156
|
)
|
|
1987
2157
|
);
|
|
1988
2158
|
} else {
|
|
1989
2159
|
opts.log(
|
|
1990
|
-
|
|
2160
|
+
import_chalk10.default.yellow(`
|
|
1991
2161
|
[--wait] Timed out after ${opts.waitTimeoutSec}s without an actionable or terminal transition (your turn never came, cycle still in flight).`)
|
|
1992
2162
|
);
|
|
1993
2163
|
}
|
|
@@ -2042,41 +2212,41 @@ function parseUntilPhase(raw) {
|
|
|
2042
2212
|
function isPhaseTerminallyUnreachable(phase, s) {
|
|
2043
2213
|
if (untilPhaseMatched(phase, s)) return false;
|
|
2044
2214
|
if (s.relationshipState === "not_found") return true;
|
|
2045
|
-
if (s.relationshipState ===
|
|
2215
|
+
if (s.relationshipState === import_sdk9.RelationshipStates.CLOSED && phase !== "relationship.closed") return true;
|
|
2046
2216
|
return false;
|
|
2047
2217
|
}
|
|
2048
2218
|
function untilPhaseMatched(phase, s) {
|
|
2049
2219
|
switch (phase) {
|
|
2050
2220
|
case "delegation.offered":
|
|
2051
|
-
return s.latestDelegation?.state ===
|
|
2221
|
+
return s.latestDelegation?.state === import_sdk9.DelegationStates.OFFERED;
|
|
2052
2222
|
case "delegation.accepted":
|
|
2053
|
-
return s.latestDelegation?.state ===
|
|
2223
|
+
return s.latestDelegation?.state === import_sdk9.DelegationStates.ACCEPTED;
|
|
2054
2224
|
case "delegation.locked":
|
|
2055
|
-
return s.latestDelegation?.state ===
|
|
2225
|
+
return s.latestDelegation?.state === import_sdk9.DelegationStates.LOCKED;
|
|
2056
2226
|
case "delegation.disputing":
|
|
2057
|
-
return s.latestDelegation?.state ===
|
|
2227
|
+
return s.latestDelegation?.state === import_sdk9.DelegationStates.DISPUTING;
|
|
2058
2228
|
case "delegation.canceled":
|
|
2059
|
-
return s.latestDelegation?.state ===
|
|
2229
|
+
return s.latestDelegation?.state === import_sdk9.DelegationStates.CANCELED;
|
|
2060
2230
|
case "delegation.declined":
|
|
2061
|
-
return s.latestDelegation?.state ===
|
|
2231
|
+
return s.latestDelegation?.state === import_sdk9.DelegationStates.DECLINED;
|
|
2062
2232
|
case "work.requested":
|
|
2063
|
-
return s.latestWorkLog?.state ===
|
|
2233
|
+
return s.latestWorkLog?.state === import_sdk9.WorkLogStates.REQUESTED;
|
|
2064
2234
|
case "work.responded":
|
|
2065
|
-
return s.latestWorkLog?.state ===
|
|
2235
|
+
return s.latestWorkLog?.state === import_sdk9.WorkLogStates.RESPONDED;
|
|
2066
2236
|
case "receipt.proposed":
|
|
2067
2237
|
return s.latestReceipt != null;
|
|
2068
2238
|
case "relationship.pending":
|
|
2069
|
-
return s.relationshipState ===
|
|
2239
|
+
return s.relationshipState === import_sdk9.RelationshipStates.PENDING;
|
|
2070
2240
|
case "relationship.active":
|
|
2071
|
-
return s.relationshipState ===
|
|
2241
|
+
return s.relationshipState === import_sdk9.RelationshipStates.ACTIVE;
|
|
2072
2242
|
case "relationship.paused":
|
|
2073
|
-
return s.relationshipState ===
|
|
2243
|
+
return s.relationshipState === import_sdk9.RelationshipStates.PAUSED;
|
|
2074
2244
|
case "relationship.closed":
|
|
2075
|
-
return s.relationshipState ===
|
|
2245
|
+
return s.relationshipState === import_sdk9.RelationshipStates.CLOSED;
|
|
2076
2246
|
case "cycle.complete":
|
|
2077
2247
|
return s.cycleComplete;
|
|
2078
2248
|
case "cycle.released":
|
|
2079
|
-
return s.latestDelegation?.state ===
|
|
2249
|
+
return s.latestDelegation?.state === import_sdk9.DelegationStates.COMPLETED;
|
|
2080
2250
|
}
|
|
2081
2251
|
}
|
|
2082
2252
|
function parseWaitInterval(raw) {
|
|
@@ -2127,7 +2297,7 @@ async function composeStatus(api, signerDid, relationshipId, signer) {
|
|
|
2127
2297
|
const relationship = relationships.find((r) => r.relationshipId === relationshipId);
|
|
2128
2298
|
const counterpartyDid = relationship ? relationship.pairDidA === signerDid ? relationship.pairDidB : relationship.pairDidA : inferCounterpartyFromEntities(signerDid, allDelegations);
|
|
2129
2299
|
const delegations = allDelegations;
|
|
2130
|
-
const latestDelegation = pickLatestLive(delegations, [...
|
|
2300
|
+
const latestDelegation = pickLatestLive(delegations, [...import_sdk9.DELEGATION_ACTIVE_STATES]);
|
|
2131
2301
|
const [workLogs, receipts] = await Promise.all([
|
|
2132
2302
|
latestDelegation ? fetchAllPages(
|
|
2133
2303
|
(after) => api.listWorkLogs(relationshipId, signer, { limit: 100, delegationId: latestDelegation.delegationId, ...after ? { after } : {} })
|
|
@@ -2191,8 +2361,8 @@ function findReceiptForWorkLog(receipts, workLog, allWorkLogs = [workLog]) {
|
|
|
2191
2361
|
};
|
|
2192
2362
|
const responseBody = workLog.responseOutput !== void 0 ? { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, output: workLog.responseOutput } } : workLog.responseError !== void 0 ? { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, error: workLog.responseError } } : null;
|
|
2193
2363
|
if (!responseBody) return null;
|
|
2194
|
-
const expectedRequestHash = (0,
|
|
2195
|
-
const expectedResponseHash = (0,
|
|
2364
|
+
const expectedRequestHash = (0, import_sdk9.canonicalSha256Hex)(requestBody);
|
|
2365
|
+
const expectedResponseHash = (0, import_sdk9.canonicalSha256Hex)(responseBody);
|
|
2196
2366
|
const matches = receipts.filter((r) => r.requestHash === expectedRequestHash && r.responseHash === expectedResponseHash);
|
|
2197
2367
|
if (matches.length > 0) return pickLatest(matches);
|
|
2198
2368
|
const respondedSiblings = allWorkLogs.filter((wl) => wl.delegationId === workLog.delegationId && (wl.responseOutput !== void 0 || wl.responseError !== void 0)).length;
|
|
@@ -2234,49 +2404,49 @@ function nextAction(input) {
|
|
|
2234
2404
|
complete: false
|
|
2235
2405
|
};
|
|
2236
2406
|
}
|
|
2237
|
-
if (relationship.state ===
|
|
2407
|
+
if (relationship.state === import_sdk9.RelationshipStates.PENDING) {
|
|
2238
2408
|
return {
|
|
2239
2409
|
hint: "Relationship is PENDING \u2014 one side owes `heyarp send-handshake-response <peer> --decision accept | decline`",
|
|
2240
2410
|
owner: "either",
|
|
2241
2411
|
complete: false
|
|
2242
2412
|
};
|
|
2243
2413
|
}
|
|
2244
|
-
if (relationship.state ===
|
|
2414
|
+
if (relationship.state === import_sdk9.RelationshipStates.PAUSED) {
|
|
2245
2415
|
return { hint: "Relationship is PAUSED \u2014 owner must `heyarp unpause` before any envelopes flow", owner: "either", complete: false };
|
|
2246
2416
|
}
|
|
2247
|
-
if (relationship.state ===
|
|
2417
|
+
if (relationship.state === import_sdk9.RelationshipStates.CLOSED) {
|
|
2248
2418
|
return { hint: "Relationship is CLOSED \u2014 terminal state, no further action possible. Start a fresh handshake to reopen.", owner: "none", complete: false };
|
|
2249
2419
|
}
|
|
2250
|
-
if (!latestDelegation || latestDelegation.state ===
|
|
2420
|
+
if (!latestDelegation || latestDelegation.state === import_sdk9.DelegationStates.DECLINED || latestDelegation.state === import_sdk9.DelegationStates.CANCELED) {
|
|
2251
2421
|
return {
|
|
2252
2422
|
hint: "No live delegation \u2014 buyer offers (terms only, no lock) `heyarp delegation offer <peer> --delegation-id <new-uuid> --title \u2026 --scope \u2026 --amount \u2026 --currency SOL:solana-devnet --deadline \u2026`, then funds the escrow lock AFTER the worker accepts via `heyarp delegation fund <del-id> --escrow-lock-from-file <path>`",
|
|
2253
2423
|
owner: "either",
|
|
2254
2424
|
complete: false
|
|
2255
2425
|
};
|
|
2256
2426
|
}
|
|
2257
|
-
if (latestDelegation.state ===
|
|
2427
|
+
if (latestDelegation.state === import_sdk9.DelegationStates.DISPUTING) {
|
|
2258
2428
|
return {
|
|
2259
2429
|
hint: `Delegation ${latestDelegation.delegationId} is DISPUTING \u2014 the buyer opened an on-chain dispute (their stake is escrowed too). The operator may rule until the dispute window lapses; after that either party closes with \`heyarp escrow dispute close ${latestDelegation.delegationId}\` (escrow returns to the buyer, both stakes return). Deadline: \`heyarp escrow show ${latestDelegation.delegationId}\`. No envelopes to send meanwhile.`,
|
|
2260
2430
|
owner: "none",
|
|
2261
2431
|
complete: false
|
|
2262
2432
|
};
|
|
2263
2433
|
}
|
|
2264
|
-
if (latestDelegation.state ===
|
|
2434
|
+
if (latestDelegation.state === import_sdk9.DelegationStates.COMPLETED) {
|
|
2265
2435
|
return {
|
|
2266
2436
|
hint: "Cycle COMPLETE \u2014 payment claimed on chain (lock paid; the receipt carries releaseStatus=paid)",
|
|
2267
2437
|
owner: "none",
|
|
2268
2438
|
complete: true
|
|
2269
2439
|
};
|
|
2270
2440
|
}
|
|
2271
|
-
if (latestDelegation.state ===
|
|
2441
|
+
if (latestDelegation.state === import_sdk9.DelegationStates.FAILED || latestDelegation.state === import_sdk9.DelegationStates.REFUNDED || latestDelegation.state === import_sdk9.DelegationStates.DISPUTE_RESOLVED) {
|
|
2272
2442
|
const stateLabel = latestDelegation.state.toUpperCase();
|
|
2273
|
-
const reason = latestDelegation.state ===
|
|
2443
|
+
const reason = latestDelegation.state === import_sdk9.DelegationStates.FAILED ? "on-chain escrow lock failed to finalise (typical causes: insufficient payer funds, wrong program-id, ProgramState PDA uninitialised \u2014 check `heyarp delegations <rel-id> --json | jq .[].escrowError` for the worker-side reason)" : latestDelegation.state === import_sdk9.DelegationStates.REFUNDED ? (
|
|
2274
2444
|
// Keyed on the DELEGATION row's releaseStatus, not the
|
|
2275
2445
|
// receipt's: in the claim-expired path the worker never
|
|
2276
2446
|
// submitted anything, so no receipt row exists to carry
|
|
2277
2447
|
// the outcome — the delegation copy is always present
|
|
2278
2448
|
// on indexer-driven terminals.
|
|
2279
|
-
latestDelegation.releaseStatus ===
|
|
2449
|
+
latestDelegation.releaseStatus === import_sdk9.LockStates.DISPUTE_CLOSED ? "the dispute window lapsed without an operator ruling and the dispute was closed \u2014 escrow returned to the buyer, both stakes returned (work was delivered but not paid)" : latestDelegation.releaseStatus === import_sdk9.LockStates.REVOKED ? "the work window lapsed without an on-chain submit \u2014 the buyer reclaimed the escrow AND the worker stake (claim_expired_work)" : "lock was refunded after expiry \u2014 no work was delivered against this delegation"
|
|
2280
2450
|
) : "admin closed the delegation via the dispute-resolution path";
|
|
2281
2451
|
return {
|
|
2282
2452
|
hint: `Delegation ${latestDelegation.delegationId} is ${stateLabel} (terminal) \u2014 ${reason}. Issue a fresh \`heyarp delegation offer <peer> --delegation-id <new-uuid> \u2026\` to retry (FSM does not auto-retry).`,
|
|
@@ -2284,7 +2454,7 @@ function nextAction(input) {
|
|
|
2284
2454
|
complete: false
|
|
2285
2455
|
};
|
|
2286
2456
|
}
|
|
2287
|
-
if (latestDelegation.state ===
|
|
2457
|
+
if (latestDelegation.state === import_sdk9.DelegationStates.OFFERED) {
|
|
2288
2458
|
const iAmOfferer = latestDelegation.offererDid === signerDid;
|
|
2289
2459
|
const stateLabel = "OFFERED";
|
|
2290
2460
|
return {
|
|
@@ -2293,7 +2463,7 @@ function nextAction(input) {
|
|
|
2293
2463
|
complete: false
|
|
2294
2464
|
};
|
|
2295
2465
|
}
|
|
2296
|
-
if (latestDelegation.state ===
|
|
2466
|
+
if (latestDelegation.state === import_sdk9.DelegationStates.ACCEPTED && !latestWorkLog) {
|
|
2297
2467
|
const iAmOfferer = latestDelegation.offererDid === signerDid;
|
|
2298
2468
|
return {
|
|
2299
2469
|
hint: iAmOfferer ? `Delegation ${latestDelegation.delegationId} is ACCEPTED \u2014 you (buyer) owe \`heyarp wallet create-lock --delegation-id ${latestDelegation.delegationId} --condition-hash <hex> ... > lock.json\` then \`heyarp delegation fund ${latestDelegation.delegationId} --escrow-lock-from-file lock.json\` (fund the escrow lock; work begins once it is LOCKED on chain)` : `Delegation ${latestDelegation.delegationId} is ACCEPTED \u2014 counterparty (the buyer) owes \`heyarp delegation fund\` to lock the escrow; wait for the delegation to reach LOCKED before working`,
|
|
@@ -2301,7 +2471,7 @@ function nextAction(input) {
|
|
|
2301
2471
|
complete: false
|
|
2302
2472
|
};
|
|
2303
2473
|
}
|
|
2304
|
-
if (latestDelegation.state ===
|
|
2474
|
+
if (latestDelegation.state === import_sdk9.DelegationStates.PENDING_LOCK_FINALIZATION && !latestWorkLog) {
|
|
2305
2475
|
return {
|
|
2306
2476
|
hint: `Delegation ${latestDelegation.delegationId} is PENDING_LOCK_FINALIZATION \u2014 the escrow lock was funded and is awaiting on-chain confirmation; both sides wait (auto-advances to LOCKED). Poll with \`heyarp status ${relationship.relationshipId} --wait --until delegation.locked\`.`,
|
|
2307
2477
|
owner: "none",
|
|
@@ -2316,7 +2486,7 @@ function nextAction(input) {
|
|
|
2316
2486
|
complete: false
|
|
2317
2487
|
};
|
|
2318
2488
|
}
|
|
2319
|
-
if (latestWorkLog.state ===
|
|
2489
|
+
if (latestWorkLog.state === import_sdk9.WorkLogStates.REQUESTED) {
|
|
2320
2490
|
const iAmPayee = latestWorkLog.payeeDid === signerDid;
|
|
2321
2491
|
return {
|
|
2322
2492
|
hint: iAmPayee ? `work_request ${latestWorkLog.requestId} is REQUESTED \u2014 you owe \`heyarp work respond\` (output OR --error)` : `work_request ${latestWorkLog.requestId} is REQUESTED \u2014 counterparty (payee) owes \`heyarp work respond\``,
|
|
@@ -2367,84 +2537,84 @@ function formatStatusReport(s) {
|
|
|
2367
2537
|
const lines = [];
|
|
2368
2538
|
lines.push(cycleHeadline(s));
|
|
2369
2539
|
lines.push("");
|
|
2370
|
-
lines.push(
|
|
2540
|
+
lines.push(import_chalk10.default.bold("Relationship"));
|
|
2371
2541
|
lines.push(` state: ${stateColor(s.relationshipState)}`);
|
|
2372
|
-
if (s.counterpartyDid) lines.push(` counterparty: ${
|
|
2542
|
+
if (s.counterpartyDid) lines.push(` counterparty: ${import_chalk10.default.cyan(s.counterpartyDid)}`);
|
|
2373
2543
|
lines.push("");
|
|
2374
|
-
lines.push(
|
|
2544
|
+
lines.push(import_chalk10.default.bold("Latest delegation"));
|
|
2375
2545
|
if (s.latestDelegation) {
|
|
2376
2546
|
lines.push(` ${s.latestDelegation.delegationId} state=${stateColor(s.latestDelegation.state)}`);
|
|
2377
|
-
lines.push(` offerer: ${
|
|
2547
|
+
lines.push(` offerer: ${import_chalk10.default.cyan(s.latestDelegation.offererDid)}`);
|
|
2378
2548
|
if (s.latestDelegation.title) lines.push(` title: ${s.latestDelegation.title}`);
|
|
2379
2549
|
if (s.latestDelegation.scopeSummary) lines.push(` scope: ${s.latestDelegation.scopeSummary}`);
|
|
2380
2550
|
} else {
|
|
2381
|
-
lines.push(
|
|
2551
|
+
lines.push(import_chalk10.default.dim(" (none)"));
|
|
2382
2552
|
}
|
|
2383
2553
|
lines.push("");
|
|
2384
|
-
lines.push(
|
|
2554
|
+
lines.push(import_chalk10.default.bold("Latest work_log"));
|
|
2385
2555
|
if (s.latestWorkLog) {
|
|
2386
2556
|
lines.push(` request_id=${s.latestWorkLog.requestId} state=${stateColor(s.latestWorkLog.state)}`);
|
|
2387
2557
|
} else {
|
|
2388
|
-
lines.push(
|
|
2558
|
+
lines.push(import_chalk10.default.dim(" (none)"));
|
|
2389
2559
|
}
|
|
2390
2560
|
lines.push("");
|
|
2391
|
-
lines.push(
|
|
2561
|
+
lines.push(import_chalk10.default.bold("Latest receipt"));
|
|
2392
2562
|
if (s.latestReceipt) {
|
|
2393
2563
|
lines.push(` ${stateColor("proposed")} verdict=${s.latestReceipt.verdictProposed}`);
|
|
2394
2564
|
} else {
|
|
2395
|
-
lines.push(
|
|
2565
|
+
lines.push(import_chalk10.default.dim(" (none)"));
|
|
2396
2566
|
}
|
|
2397
2567
|
lines.push("");
|
|
2398
|
-
lines.push(
|
|
2399
|
-
const ownerLabel = s.nextActionOwner === "me" ?
|
|
2568
|
+
lines.push(import_chalk10.default.bold("Next action"));
|
|
2569
|
+
const ownerLabel = s.nextActionOwner === "me" ? import_chalk10.default.green("me") : s.nextActionOwner === "counterparty" ? import_chalk10.default.yellow("counterparty") : s.nextActionOwner === "either" ? import_chalk10.default.cyan("either side") : import_chalk10.default.dim("\u2014");
|
|
2400
2570
|
lines.push(` whose turn: ${ownerLabel}`);
|
|
2401
2571
|
lines.push(` hint: ${s.nextActionHint}`);
|
|
2402
|
-
if (s.cycleComplete) lines.push(` ${
|
|
2572
|
+
if (s.cycleComplete) lines.push(` ${import_chalk10.default.green("\u2713 Cycle complete.")}`);
|
|
2403
2573
|
return lines.join("\n");
|
|
2404
2574
|
}
|
|
2405
2575
|
function cycleHeadline(s) {
|
|
2406
2576
|
if (s.cycleComplete) {
|
|
2407
|
-
return `${
|
|
2577
|
+
return `${import_chalk10.default.bold("Cycle:")} ${import_chalk10.default.green.bold("COMPLETE")} ${import_chalk10.default.dim("\u2014 payment proven on chain")}`;
|
|
2408
2578
|
}
|
|
2409
2579
|
switch (s.relationshipState) {
|
|
2410
2580
|
case "not_found":
|
|
2411
|
-
return `${
|
|
2581
|
+
return `${import_chalk10.default.bold("Cycle:")} ${import_chalk10.default.red.bold("NOT FOUND")} ${import_chalk10.default.dim("\u2014 relationship missing or signer is not a member")}`;
|
|
2412
2582
|
case "unknown":
|
|
2413
|
-
return `${
|
|
2414
|
-
case
|
|
2415
|
-
return `${
|
|
2416
|
-
case
|
|
2417
|
-
return `${
|
|
2418
|
-
case
|
|
2419
|
-
return `${
|
|
2420
|
-
case
|
|
2583
|
+
return `${import_chalk10.default.bold("Cycle:")} ${import_chalk10.default.yellow.bold("UNKNOWN")} ${import_chalk10.default.dim("\u2014 state probe inconclusive; hint below is advisory")}`;
|
|
2584
|
+
case import_sdk9.RelationshipStates.CLOSED:
|
|
2585
|
+
return `${import_chalk10.default.bold("Cycle:")} ${import_chalk10.default.red.bold("CLOSED")} ${import_chalk10.default.dim("\u2014 relationship terminal, no further protocol action")}`;
|
|
2586
|
+
case import_sdk9.RelationshipStates.PAUSED:
|
|
2587
|
+
return `${import_chalk10.default.bold("Cycle:")} ${import_chalk10.default.yellow.bold("PAUSED")} ${import_chalk10.default.dim("\u2014 relationship soft-disabled, resume to continue")}`;
|
|
2588
|
+
case import_sdk9.RelationshipStates.PENDING:
|
|
2589
|
+
return `${import_chalk10.default.bold("Cycle:")} ${import_chalk10.default.yellow.bold("PENDING")} ${import_chalk10.default.dim("\u2014 awaiting handshake_response")}`;
|
|
2590
|
+
case import_sdk9.RelationshipStates.ACTIVE:
|
|
2421
2591
|
default:
|
|
2422
|
-
return `${
|
|
2592
|
+
return `${import_chalk10.default.bold("Cycle:")} ${import_chalk10.default.cyan.bold("ACTIVE")} ${import_chalk10.default.dim('\u2014 work in progress; see "Next action" below')}`;
|
|
2423
2593
|
}
|
|
2424
2594
|
}
|
|
2425
2595
|
function stateColor(state) {
|
|
2426
|
-
const c = state === "active" || state === "accepted" || state === "locked" || state === "responded" || state === "completed" ?
|
|
2596
|
+
const c = state === "active" || state === "accepted" || state === "locked" || state === "responded" || state === "completed" ? import_chalk10.default.green : state === "pending" || state === "requested" || state === "offered" || state === "pending_lock_finalization" ? import_chalk10.default.yellow : state === "closed" || state === "declined" || state === "canceled" || state === "replaced" || state === "not_found" || // Terminal failure states deserve the same red
|
|
2427
2597
|
// treatment as declined/canceled so an operator
|
|
2428
2598
|
// scanning `heyarp status` immediately sees
|
|
2429
2599
|
// "this is dead, don't follow the hint blindly".
|
|
2430
|
-
state === "failed" || state === "refunded" || state === "dispute_resolved" ?
|
|
2600
|
+
state === "failed" || state === "refunded" || state === "dispute_resolved" ? import_chalk10.default.red : import_chalk10.default.cyan;
|
|
2431
2601
|
return c(state);
|
|
2432
2602
|
}
|
|
2433
2603
|
|
|
2434
2604
|
// src/commands/wallet.ts
|
|
2435
|
-
var
|
|
2605
|
+
var import_sdk12 = require("@heyanon-arp/sdk");
|
|
2436
2606
|
var import_utils = require("@noble/hashes/utils");
|
|
2437
2607
|
var import_web3 = require("@solana/web3.js");
|
|
2438
2608
|
init_api();
|
|
2439
2609
|
init_config();
|
|
2440
2610
|
|
|
2441
2611
|
// src/solana/escrow-ix.ts
|
|
2442
|
-
var
|
|
2612
|
+
var import_sdk10 = require("@heyanon-arp/sdk");
|
|
2443
2613
|
|
|
2444
2614
|
// src/commands/token-amount.ts
|
|
2445
|
-
var
|
|
2615
|
+
var import_sdk11 = require("@heyanon-arp/sdk");
|
|
2446
2616
|
function toBaseUnits(amountDecimal, decimals) {
|
|
2447
|
-
if (!(0,
|
|
2617
|
+
if (!(0, import_sdk11.isDecimalAmountString)(amountDecimal)) {
|
|
2448
2618
|
throw new Error(`amount '${amountDecimal}' is not a non-negative decimal number`);
|
|
2449
2619
|
}
|
|
2450
2620
|
if (!Number.isInteger(decimals) || decimals < 0 || decimals > 255) {
|
|
@@ -2473,8 +2643,8 @@ function normaliseDelegationId(raw) {
|
|
|
2473
2643
|
}
|
|
2474
2644
|
throw new Error(`wallet: --delegation-id must be either 'del_<uuid>' or a bare canonical-lowercase UUID (got '${raw}')`);
|
|
2475
2645
|
}
|
|
2476
|
-
var SPL_TOKEN_PROGRAM_ID2 = new import_web3.PublicKey(
|
|
2477
|
-
var ASSOCIATED_TOKEN_PROGRAM_ID2 = new import_web3.PublicKey(
|
|
2646
|
+
var SPL_TOKEN_PROGRAM_ID2 = new import_web3.PublicKey(import_sdk12.SPL_TOKEN_PROGRAM_ID_BASE58);
|
|
2647
|
+
var ASSOCIATED_TOKEN_PROGRAM_ID2 = new import_web3.PublicKey(import_sdk12.ASSOCIATED_TOKEN_PROGRAM_ID_BASE58);
|
|
2478
2648
|
var FALLBACK_RPC_URL = "https://api.mainnet-beta.solana.com";
|
|
2479
2649
|
function resolveRpcUrl(opts) {
|
|
2480
2650
|
if (opts.rpcUrl !== void 0 && opts.rpcUrl !== "") return opts.rpcUrl;
|
|
@@ -2494,7 +2664,7 @@ function redactRpcUrl(url) {
|
|
|
2494
2664
|
return "<redacted>";
|
|
2495
2665
|
}
|
|
2496
2666
|
}
|
|
2497
|
-
var FALLBACK_PROGRAM_ID =
|
|
2667
|
+
var FALLBACK_PROGRAM_ID = import_sdk12.ESCROW_PROGRAM_ID_BASE58;
|
|
2498
2668
|
async function resolveProgramIdWithSource(api, opts) {
|
|
2499
2669
|
if (opts.programId !== void 0 && opts.programId !== "") {
|
|
2500
2670
|
return { programId: opts.programId, source: "flag" };
|
|
@@ -2578,7 +2748,7 @@ async function derivePdasHandler(opts) {
|
|
|
2578
2748
|
const normalisedDelegationId = normaliseDelegationId(opts.delegationId);
|
|
2579
2749
|
const api = new ArpApiClient(opts.server);
|
|
2580
2750
|
const programId = new import_web3.PublicKey(await resolveProgramIdStrict(api, opts, "wallet derive-pdas"));
|
|
2581
|
-
const lockIdBytes = (0,
|
|
2751
|
+
const lockIdBytes = (0, import_sdk12.deriveLockId)(normalisedDelegationId);
|
|
2582
2752
|
const lockIdSeed = Buffer.from(lockIdBytes);
|
|
2583
2753
|
const lockIdHex = Buffer.from(lockIdBytes).toString("hex");
|
|
2584
2754
|
const [lockPda] = import_web3.PublicKey.findProgramAddressSync([Buffer.from("lock"), lockIdSeed], programId);
|
|
@@ -2597,11 +2767,11 @@ async function derivePdasHandler(opts) {
|
|
|
2597
2767
|
};
|
|
2598
2768
|
}
|
|
2599
2769
|
var TERMINAL_METHOD = {
|
|
2600
|
-
[
|
|
2601
|
-
[
|
|
2602
|
-
[
|
|
2603
|
-
[
|
|
2604
|
-
[
|
|
2770
|
+
[import_sdk12.LockStates.PAID]: "claim_work_payment",
|
|
2771
|
+
[import_sdk12.LockStates.CANCELED]: "cancel_lock",
|
|
2772
|
+
[import_sdk12.LockStates.REVOKED]: "claim_expired_work",
|
|
2773
|
+
[import_sdk12.LockStates.DISPUTE_RESOLVED]: "resolve_dispute",
|
|
2774
|
+
[import_sdk12.LockStates.DISPUTE_CLOSED]: "close_dispute"
|
|
2605
2775
|
};
|
|
2606
2776
|
function registerVerifyRelease(cmd) {
|
|
2607
2777
|
cmd.command("verify-release").description(
|
|
@@ -2646,10 +2816,10 @@ async function verifyReleaseHandler(opts) {
|
|
|
2646
2816
|
const programId = new import_web3.PublicKey(await resolveProgramIdStrict(api, opts));
|
|
2647
2817
|
const rpcUrl = resolveRpcUrlStrict(opts);
|
|
2648
2818
|
const conn = new import_web3.Connection(rpcUrl, "confirmed");
|
|
2649
|
-
const fetched = await (0,
|
|
2650
|
-
const lockId = (0,
|
|
2651
|
-
const lockPda = (0,
|
|
2652
|
-
const escrowPda = (0,
|
|
2819
|
+
const fetched = await (0, import_sdk10.fetchLockAccount)(conn, programId, normalisedDelegationId);
|
|
2820
|
+
const lockId = (0, import_sdk12.deriveLockId)(normalisedDelegationId);
|
|
2821
|
+
const lockPda = (0, import_sdk10.deriveLockPda)(programId, lockId);
|
|
2822
|
+
const escrowPda = (0, import_sdk10.deriveEscrowPda)(programId, lockId);
|
|
2653
2823
|
if (!fetched) {
|
|
2654
2824
|
return {
|
|
2655
2825
|
delegation_id: normalisedDelegationId,
|
|
@@ -2668,7 +2838,7 @@ async function verifyReleaseHandler(opts) {
|
|
|
2668
2838
|
lock_pda: lockPda.toBase58(),
|
|
2669
2839
|
escrow_pda: escrowPda.toBase58(),
|
|
2670
2840
|
lock_account_exists: true,
|
|
2671
|
-
released: status ===
|
|
2841
|
+
released: status === import_sdk12.LockStates.PAID,
|
|
2672
2842
|
status,
|
|
2673
2843
|
...TERMINAL_METHOD[status] !== void 0 ? { release_method: TERMINAL_METHOD[status] } : {},
|
|
2674
2844
|
lock_state: lock.stateByte,
|
|
@@ -2678,23 +2848,23 @@ async function verifyReleaseHandler(opts) {
|
|
|
2678
2848
|
}
|
|
2679
2849
|
function renderStatusLine(status) {
|
|
2680
2850
|
switch (status) {
|
|
2681
|
-
case
|
|
2851
|
+
case import_sdk12.LockStates.PAID:
|
|
2682
2852
|
return "\u2713 paid \u2014 claim_work_payment landed (buyer approval or post-review self-claim); the payee was paid net of any protocol fee";
|
|
2683
|
-
case
|
|
2853
|
+
case import_sdk12.LockStates.CREATED:
|
|
2684
2854
|
return "\u2717 created \u2014 funded, awaiting the worker accept_lock (stake) \u2014 or a buyer cancel";
|
|
2685
|
-
case
|
|
2855
|
+
case import_sdk12.LockStates.IN_PROGRESS:
|
|
2686
2856
|
return "\u2717 in_progress \u2014 worker accepted + staked; work window running";
|
|
2687
|
-
case
|
|
2857
|
+
case import_sdk12.LockStates.SUBMITTED:
|
|
2688
2858
|
return "\u2717 submitted \u2014 work delivered on-chain; review window running (buyer claims to approve, disputes to refuse; worker self-claims after expiry)";
|
|
2689
|
-
case
|
|
2859
|
+
case import_sdk12.LockStates.DISPUTING:
|
|
2690
2860
|
return "\u2717 disputing \u2014 buyer disputed; operator has the dispute window to rule, after that either party can close";
|
|
2691
|
-
case
|
|
2861
|
+
case import_sdk12.LockStates.CANCELED:
|
|
2692
2862
|
return "\u2717 canceled \u2014 buyer canceled pre-accept; escrow returned";
|
|
2693
|
-
case
|
|
2863
|
+
case import_sdk12.LockStates.REVOKED:
|
|
2694
2864
|
return "\u2717 revoked \u2014 work window lapsed unsubmitted; buyer reclaimed the escrow + the worker stake";
|
|
2695
|
-
case
|
|
2865
|
+
case import_sdk12.LockStates.DISPUTE_RESOLVED:
|
|
2696
2866
|
return "\u2717 dispute_resolved \u2014 operator ruled; winner took the escrow per the on-chain split";
|
|
2697
|
-
case
|
|
2867
|
+
case import_sdk12.LockStates.DISPUTE_CLOSED:
|
|
2698
2868
|
return "\u2717 dispute_closed \u2014 dispute window lapsed unresolved; escrow returned to the buyer, stakes returned";
|
|
2699
2869
|
case "lock_never_created":
|
|
2700
2870
|
return "\u2717 lock_never_created \u2014 no Lock PDA on this cluster/program; create_lock never fired (or wrong --rpc-url/--program-id)";
|
|
@@ -2880,7 +3050,7 @@ async function createLockHandler(opts) {
|
|
|
2880
3050
|
if (clusterTag !== 0 && clusterTag !== 1) {
|
|
2881
3051
|
throw new Error(`--cluster-tag must be 0 (devnet) or 1 (mainnet) (got ${clusterTag})`);
|
|
2882
3052
|
}
|
|
2883
|
-
const clusterCaip2 = clusterTag === 1 ?
|
|
3053
|
+
const clusterCaip2 = clusterTag === 1 ? import_sdk12.SOLANA_CLUSTER_IDS["solana-mainnet"] : import_sdk12.SOLANA_CLUSTER_IDS["solana-devnet"];
|
|
2884
3054
|
const expectedLockAsset = typeof opts.mintPubkey === "string" && opts.mintPubkey !== "" ? { kind: "spl", mint: parsePubkey(opts.mintPubkey, "--mint-pubkey").toBase58(), cluster: clusterCaip2 } : { kind: "native" };
|
|
2885
3055
|
if (!offlineMode) {
|
|
2886
3056
|
await preflightLockCurrency(api, agent, normalisedDelegationId, expectedLockAsset);
|
|
@@ -2890,8 +3060,8 @@ async function createLockHandler(opts) {
|
|
|
2890
3060
|
const conn = new import_web3.Connection(rpcUrl, "confirmed");
|
|
2891
3061
|
const asset = await resolveCreateLockAsset(conn, opts, payerKp.publicKey, clusterCaip2);
|
|
2892
3062
|
const amount = asset.amount;
|
|
2893
|
-
const lockIdBytes = (0,
|
|
2894
|
-
const ix = (0,
|
|
3063
|
+
const lockIdBytes = (0, import_sdk12.deriveLockId)(normalisedDelegationId);
|
|
3064
|
+
const ix = (0, import_sdk10.buildCreateLockIx)({
|
|
2895
3065
|
programId,
|
|
2896
3066
|
lockId: lockIdBytes,
|
|
2897
3067
|
payer: payerKp.publicKey,
|
|
@@ -2982,7 +3152,7 @@ function registerDelegationCommands(root) {
|
|
|
2982
3152
|
registerCancel(cmd);
|
|
2983
3153
|
}
|
|
2984
3154
|
function registerOffer(parent) {
|
|
2985
|
-
parent.command("offer").description("Open a new delegation addressed to <recipient-did> with the agreed terms INLINE (no escrow lock \u2014 fund AFTER acceptance via `delegation fund`).").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--delegation-id <uuid>", "Override the auto-generated delegation id (UUID). Reuse the SAME id at `heyarp delegation fund` time. Useful for replay / scripting.").option("--title <s>", "Required: human-readable title for the offer").option("--brief <json>", "Optional structured brief (JSON object)").option("--criterion <s>", "acceptance_criteria \u2014 repeatable; pass --criterion once per bullet", collectRepeated, []).option("--deadline <rfc3339>", 'Optional RFC 3339 deadline (e.g. "2026-12-31T23:59:59Z")').option("--scope <text>", "scope_summary \u2014 short prose describing the agreed work. Required.").option("--amount <s>", 'Optional decimal-as-string amount (e.g. "10.00"). REQUIRES --currency if set.').option("--currency <s>", `Asset identifier: shorthand (${
|
|
3155
|
+
parent.command("offer").description("Open a new delegation addressed to <recipient-did> with the agreed terms INLINE (no escrow lock \u2014 fund AFTER acceptance via `delegation fund`).").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--delegation-id <uuid>", "Override the auto-generated delegation id (UUID). Reuse the SAME id at `heyarp delegation fund` time. Useful for replay / scripting.").option("--title <s>", "Required: human-readable title for the offer").option("--brief <json>", "Optional structured brief (JSON object)").option("--criterion <s>", "acceptance_criteria \u2014 repeatable; pass --criterion once per bullet", collectRepeated, []).option("--deadline <rfc3339>", 'Optional RFC 3339 deadline (e.g. "2026-12-31T23:59:59Z")').option("--scope <text>", "scope_summary \u2014 short prose describing the agreed work. Required.").option("--amount <s>", 'Optional decimal-as-string amount (e.g. "10.00"). REQUIRES --currency if set.').option("--currency <s>", `Asset identifier: shorthand (${import_sdk13.WELL_KNOWN_ASSET_KEYS.join("|")}) OR raw CAIP-19 string.`).option("--currency-decimals <n>", "Decimal places for base-unit conversion (0-18). Required only when --currency is raw CAIP-19.").option("--currency-symbol <s>", 'Optional UI hint ("USDC", "SOL"). Max 16 chars.').option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk13.MAX_ENVELOPE_TTL_SECONDS} = 24h)`, "3600").option("--require-online", "Abort (exit 1, CLI_RECIPIENT_OFFLINE) if the recipient is not reachable now, instead of warning and sending to their inbox", false).option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
|
|
2986
3156
|
"--json",
|
|
2987
3157
|
'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"offer", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + the "reference this delegation" hints move to stderr; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
|
|
2988
3158
|
false
|
|
@@ -3107,9 +3277,9 @@ async function runOffer(recipientDid, opts) {
|
|
|
3107
3277
|
}
|
|
3108
3278
|
const terms = parseOfferTerms("delegation offer", opts);
|
|
3109
3279
|
const offeredAssetId = terms.currency?.asset_id;
|
|
3110
|
-
if (offeredAssetId && !(0,
|
|
3280
|
+
if (offeredAssetId && !(0, import_sdk13.isWhitelistedAssetId)(offeredAssetId)) {
|
|
3111
3281
|
console.error(
|
|
3112
|
-
|
|
3282
|
+
import_chalk11.default.yellow(
|
|
3113
3283
|
`warning: currency '${offeredAssetId}' is not in the static payment whitelist \u2014 the server will reject the offer (DELEGATION_ASSET_NOT_ALLOWED) unless its deploy registers this asset. See 'heyarp assets'.`
|
|
3114
3284
|
)
|
|
3115
3285
|
);
|
|
@@ -3128,43 +3298,44 @@ async function runOffer(recipientDid, opts) {
|
|
|
3128
3298
|
const api = new ArpApiClient(opts.server);
|
|
3129
3299
|
const sender = resolveSenderAgent("delegation offer", opts.server, opts.fromDid, opts.from);
|
|
3130
3300
|
const content = {
|
|
3131
|
-
action:
|
|
3301
|
+
action: import_sdk13.DelegationActions.OFFER,
|
|
3132
3302
|
delegation_id: delegationId,
|
|
3133
3303
|
title: opts.title,
|
|
3134
3304
|
...terms
|
|
3135
3305
|
};
|
|
3136
3306
|
const body = { type: "delegation", content };
|
|
3137
|
-
progress(opts.json,
|
|
3138
|
-
progress(opts.json,
|
|
3139
|
-
progress(opts.json,
|
|
3140
|
-
progress(opts.json,
|
|
3307
|
+
progress(opts.json, import_chalk11.default.dim(`Server: ${api.serverUrl}`));
|
|
3308
|
+
progress(opts.json, import_chalk11.default.dim(`Sender: ${sender.did}`));
|
|
3309
|
+
progress(opts.json, import_chalk11.default.dim(`Recipient: ${recipientDid}`));
|
|
3310
|
+
progress(opts.json, import_chalk11.default.dim(`Delegation: ${delegationId}`));
|
|
3311
|
+
await guardRecipientReachable(api, recipientDid, { requireOnline: opts.requireOnline });
|
|
3141
3312
|
let result;
|
|
3142
3313
|
try {
|
|
3143
3314
|
result = await sendDelegationEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
3144
3315
|
} catch (err) {
|
|
3145
|
-
if (err instanceof ApiError && err.payload.code ===
|
|
3316
|
+
if (err instanceof ApiError && err.payload.code === import_sdk13.DelegationOfferRejectionCodes.ASSET_NOT_ALLOWED) {
|
|
3146
3317
|
const d = err.payload.details;
|
|
3147
|
-
console.error(
|
|
3318
|
+
console.error(import_chalk11.default.yellow(`
|
|
3148
3319
|
The server's payment-asset whitelist rejected this currency.`));
|
|
3149
3320
|
if (d !== void 0) {
|
|
3150
|
-
console.error(
|
|
3151
|
-
console.error(
|
|
3321
|
+
console.error(import_chalk11.default.dim(` offered: ${JSON.stringify(d.offered)}`));
|
|
3322
|
+
console.error(import_chalk11.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
|
|
3152
3323
|
}
|
|
3153
|
-
console.error(
|
|
3324
|
+
console.error(import_chalk11.default.dim(`
|
|
3154
3325
|
See the whitelist (shorthand keys + canonical decimals):
|
|
3155
3326
|
heyarp assets
|
|
3156
3327
|
then re-offer with a whitelisted --currency.`));
|
|
3157
3328
|
}
|
|
3158
|
-
if (err instanceof ApiError && err.payload.code ===
|
|
3329
|
+
if (err instanceof ApiError && err.payload.code === import_sdk13.DelegationOfferRejectionCodes.PRICING_MISMATCH) {
|
|
3159
3330
|
const d = err.payload.details;
|
|
3160
|
-
console.error(
|
|
3331
|
+
console.error(import_chalk11.default.yellow(`
|
|
3161
3332
|
The recipient's published accept-prefs rejected this offer${d?.reason ? ` (mismatch: ${d.reason})` : ""}.`));
|
|
3162
3333
|
if (d !== void 0) {
|
|
3163
|
-
console.error(
|
|
3164
|
-
console.error(
|
|
3334
|
+
console.error(import_chalk11.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
|
|
3335
|
+
console.error(import_chalk11.default.dim(` offered: ${JSON.stringify(d.offered)}`));
|
|
3165
3336
|
}
|
|
3166
3337
|
console.error(
|
|
3167
|
-
|
|
3338
|
+
import_chalk11.default.dim(
|
|
3168
3339
|
`
|
|
3169
3340
|
Check what the recipient accepts BEFORE offering:
|
|
3170
3341
|
heyarp agents accept-prefs show ${recipientDid}
|
|
@@ -3172,12 +3343,12 @@ then re-run with matching --currency / --amount.`
|
|
|
3172
3343
|
)
|
|
3173
3344
|
);
|
|
3174
3345
|
}
|
|
3175
|
-
if (err instanceof ApiError && err.payload.code ===
|
|
3346
|
+
if (err instanceof ApiError && err.payload.code === import_sdk13.DelegationOfferRejectionCodes.CAPACITY_EXCEEDED) {
|
|
3176
3347
|
const d = err.payload.details;
|
|
3177
3348
|
const cap = d?.maxActive === 0 ? "closed for new offers (busy)" : `at capacity (${d?.currentActive}/${d?.maxActive} active delegations)`;
|
|
3178
|
-
console.error(
|
|
3349
|
+
console.error(import_chalk11.default.yellow(`
|
|
3179
3350
|
The recipient is ${cap}.`));
|
|
3180
|
-
console.error(
|
|
3351
|
+
console.error(import_chalk11.default.dim("\nThis is TRANSIENT \u2014 your terms are fine. Retry the same offer later, or pick another worker (`heyarp agents --tag \u2026`)."));
|
|
3181
3352
|
}
|
|
3182
3353
|
throw err;
|
|
3183
3354
|
}
|
|
@@ -3195,15 +3366,15 @@ The recipient is ${cap}.`));
|
|
|
3195
3366
|
});
|
|
3196
3367
|
} else {
|
|
3197
3368
|
printIngestResult(result);
|
|
3198
|
-
console.log(
|
|
3369
|
+
console.log(import_chalk11.default.dim(`
|
|
3199
3370
|
Reference this delegation on subsequent calls with:`));
|
|
3200
|
-
console.log(
|
|
3201
|
-
console.log(
|
|
3202
|
-
console.log(
|
|
3203
|
-
console.log(
|
|
3371
|
+
console.log(import_chalk11.default.dim(` heyarp delegation accept ${result.relationshipId} ${delegationId}`));
|
|
3372
|
+
console.log(import_chalk11.default.dim(` heyarp delegation decline ${result.relationshipId} ${delegationId}`));
|
|
3373
|
+
console.log(import_chalk11.default.dim(` heyarp delegation cancel ${result.relationshipId} ${delegationId}`));
|
|
3374
|
+
console.log(import_chalk11.default.dim(`
|
|
3204
3375
|
After the worker accepts, fund the escrow lock:`));
|
|
3205
|
-
console.log(
|
|
3206
|
-
console.log(
|
|
3376
|
+
console.log(import_chalk11.default.dim(` heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash <hex> ... > lock.json`));
|
|
3377
|
+
console.log(import_chalk11.default.dim(` heyarp delegation fund ${delegationId} --escrow-lock-from-file lock.json`));
|
|
3207
3378
|
}
|
|
3208
3379
|
if (opts.waitUntil && !opts.json) {
|
|
3209
3380
|
const untilPhase = parseUntilPhase(opts.waitUntil);
|
|
@@ -3226,7 +3397,7 @@ After the worker accepts, fund the escrow lock:`));
|
|
|
3226
3397
|
}
|
|
3227
3398
|
}
|
|
3228
3399
|
function registerFund(parent) {
|
|
3229
|
-
parent.command("fund").description("Fund an ACCEPTED delegation with the escrow lock (buyer-only). Run AFTER the worker accepts the offer.").argument("<delegation-id>", "Delegation UUID (the one you offered + the worker accepted)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--ttl <seconds>", `Envelope TTL in seconds (max ${
|
|
3400
|
+
parent.command("fund").description("Fund an ACCEPTED delegation with the escrow lock (buyer-only). Run AFTER the worker accepts the offer.").argument("<delegation-id>", "Delegation UUID (the one you offered + the worker accepted)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk13.MAX_ENVELOPE_TTL_SECONDS} = 24h)`, "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
|
|
3230
3401
|
"--json",
|
|
3231
3402
|
'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"fund", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude moves off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
|
|
3232
3403
|
false
|
|
@@ -3287,23 +3458,23 @@ async function runFund(delegationId, opts) {
|
|
|
3287
3458
|
}
|
|
3288
3459
|
if (result2.kind === "skipped_no_expected_program_id") {
|
|
3289
3460
|
console.error(
|
|
3290
|
-
|
|
3461
|
+
import_chalk11.default.yellow(
|
|
3291
3462
|
"\u26A0 delegation fund: no authoritative expected program-id available (--program-id missing, ARP_ESCROW_PROGRAM_ID env unset, server protocol-fee unreachable). Pre-flight skipped; server-side ESC_LOCK_TX_PROGRAM_ID_MISMATCH check is the only backstop. Set ARP_ESCROW_PROGRAM_ID or pass --program-id to enable pre-flight."
|
|
3292
3463
|
)
|
|
3293
3464
|
);
|
|
3294
3465
|
}
|
|
3295
3466
|
}
|
|
3296
|
-
const content = { action:
|
|
3467
|
+
const content = { action: import_sdk13.DelegationActions.FUND, delegation_id: delegationId };
|
|
3297
3468
|
const body = { type: "delegation", content };
|
|
3298
3469
|
const attachments = { escrow_lock: escrowResult.attachment };
|
|
3299
|
-
progress(opts.json,
|
|
3300
|
-
progress(opts.json,
|
|
3301
|
-
progress(opts.json,
|
|
3302
|
-
progress(opts.json,
|
|
3303
|
-
progress(opts.json,
|
|
3470
|
+
progress(opts.json, import_chalk11.default.dim(`Server: ${api.serverUrl}`));
|
|
3471
|
+
progress(opts.json, import_chalk11.default.dim(`Sender: ${sender.did}`));
|
|
3472
|
+
progress(opts.json, import_chalk11.default.dim(`Recipient: ${resolved.recipientDid}`));
|
|
3473
|
+
progress(opts.json, import_chalk11.default.dim(`Relationship: ${resolved.relationshipId}`));
|
|
3474
|
+
progress(opts.json, import_chalk11.default.dim(`Delegation: ${delegationId} (action=fund)`));
|
|
3304
3475
|
{
|
|
3305
3476
|
const a = escrowResult.attachment;
|
|
3306
|
-
progress(opts.json,
|
|
3477
|
+
progress(opts.json, import_chalk11.default.dim(`Escrow lock attached: lock_id=${a.lock_id} amount=${a.amount} asset_id=${a.asset_id}`));
|
|
3307
3478
|
}
|
|
3308
3479
|
const result = await sendDelegationEnvelope({
|
|
3309
3480
|
api,
|
|
@@ -3329,7 +3500,7 @@ async function runFund(delegationId, opts) {
|
|
|
3329
3500
|
});
|
|
3330
3501
|
} else {
|
|
3331
3502
|
printIngestResult(result);
|
|
3332
|
-
console.log(
|
|
3503
|
+
console.log(import_chalk11.default.dim("\nThe worker waits for the on-chain lock to confirm (LOCKED), then begins work."));
|
|
3333
3504
|
}
|
|
3334
3505
|
if (opts.waitUntil && !opts.json) {
|
|
3335
3506
|
const untilPhase = parseUntilPhase(opts.waitUntil);
|
|
@@ -3394,7 +3565,7 @@ function registerDecline(parent) {
|
|
|
3394
3565
|
"--reason <code>",
|
|
3395
3566
|
// surface the closed enum at help time so operators
|
|
3396
3567
|
// don't have to read source to find acceptable values.
|
|
3397
|
-
`Required: decline reason code (one of: ${
|
|
3568
|
+
`Required: decline reason code (one of: ${import_sdk13.DECLINE_REASONS.join(", ")}). Carried in body.content.reason so the counterparty's reactor can branch on it.`
|
|
3398
3569
|
).option("--reason-detail <s>", 'Optional free-text elaboration alongside --reason (e.g. "rate floor 0.20 USDC"). Max 512 chars.').option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
|
|
3399
3570
|
"--json",
|
|
3400
3571
|
'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"decline", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + pending-lock poll chatter move off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
|
|
@@ -3431,7 +3602,7 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3431
3602
|
const lockWaitTimeoutSec = parseLockWaitTimeout(cmdName, opts.lockWaitTimeout);
|
|
3432
3603
|
const lockWaitIntervalSec = parseLockWaitInterval(cmdName, opts.lockWaitInterval);
|
|
3433
3604
|
let declinePayload = null;
|
|
3434
|
-
if (action ===
|
|
3605
|
+
if (action === import_sdk13.DelegationActions.DECLINE) {
|
|
3435
3606
|
const reason = parseDeclineReason(cmdName, opts.reason);
|
|
3436
3607
|
const validatedDetail = parseReasonDetail(cmdName, opts.reasonDetail);
|
|
3437
3608
|
declinePayload = validatedDetail ? { reason, reasonDetail: validatedDetail } : { reason };
|
|
@@ -3440,7 +3611,7 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3440
3611
|
const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid, opts.from);
|
|
3441
3612
|
const signer = makeSigner(sender);
|
|
3442
3613
|
const resolved = await resolveDelegationRefs(cmdName, api, signer, { relationshipId, delegationId, action, selfDid: sender.did });
|
|
3443
|
-
if (resolved.state ===
|
|
3614
|
+
if (resolved.state === import_sdk13.DelegationStates.PENDING_LOCK_FINALIZATION && opts.waitForLock !== false) {
|
|
3444
3615
|
await awaitDelegationLockFinalized(cmdName, api, signer, {
|
|
3445
3616
|
relationshipId,
|
|
3446
3617
|
delegationId,
|
|
@@ -3462,10 +3633,10 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3462
3633
|
if (declinePayload.reasonDetail) content.reason_detail = declinePayload.reasonDetail;
|
|
3463
3634
|
}
|
|
3464
3635
|
const body = { type: "delegation", content };
|
|
3465
|
-
progress(opts.json,
|
|
3466
|
-
progress(opts.json,
|
|
3467
|
-
progress(opts.json,
|
|
3468
|
-
progress(opts.json,
|
|
3636
|
+
progress(opts.json, import_chalk11.default.dim(`Server: ${api.serverUrl}`));
|
|
3637
|
+
progress(opts.json, import_chalk11.default.dim(`Sender: ${sender.did}`));
|
|
3638
|
+
progress(opts.json, import_chalk11.default.dim(`Relationship: ${relationshipId}`));
|
|
3639
|
+
progress(opts.json, import_chalk11.default.dim(`Delegation: ${delegationId} (action=${action}${action === import_sdk13.DelegationActions.DECLINE ? `, reason=${content.reason}` : ""})`));
|
|
3469
3640
|
const result = await sendDelegationEnvelope({
|
|
3470
3641
|
api,
|
|
3471
3642
|
sender,
|
|
@@ -3494,9 +3665,9 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3494
3665
|
async function sendDelegationEnvelope(args) {
|
|
3495
3666
|
const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
|
|
3496
3667
|
const protectedBlock = {
|
|
3497
|
-
protocol_version:
|
|
3498
|
-
purpose:
|
|
3499
|
-
message_id: (0,
|
|
3668
|
+
protocol_version: import_sdk13.CURRENT_PROTOCOL_VERSION,
|
|
3669
|
+
purpose: import_sdk13.Purpose.ENVELOPE,
|
|
3670
|
+
message_id: (0, import_sdk13.uuidV4)(),
|
|
3500
3671
|
sender_did: args.sender.did,
|
|
3501
3672
|
recipient_did: args.recipientDid,
|
|
3502
3673
|
// `relationship_id: null` matches the handshake
|
|
@@ -3505,20 +3676,20 @@ async function sendDelegationEnvelope(args) {
|
|
|
3505
3676
|
// existing relationship row.
|
|
3506
3677
|
relationship_id: null,
|
|
3507
3678
|
sender_sequence: nextSequence,
|
|
3508
|
-
sender_nonce: (0,
|
|
3509
|
-
timestamp: (0,
|
|
3510
|
-
expires_at: (0,
|
|
3679
|
+
sender_nonce: (0, import_sdk13.senderNonce)(),
|
|
3680
|
+
timestamp: (0, import_sdk13.rfc3339)(),
|
|
3681
|
+
expires_at: (0, import_sdk13.expiresAt)(args.ttlSeconds),
|
|
3511
3682
|
delivery_id: null
|
|
3512
3683
|
};
|
|
3513
3684
|
const signer = makeSigner(args.sender);
|
|
3514
|
-
const envelope = (0,
|
|
3685
|
+
const envelope = (0, import_sdk13.signEnvelope)({
|
|
3515
3686
|
protected: protectedBlock,
|
|
3516
3687
|
body: args.body,
|
|
3517
3688
|
identitySecretKey: signer.identitySecretKey,
|
|
3518
3689
|
attachments: args.attachments
|
|
3519
3690
|
});
|
|
3520
3691
|
if (args.verbose) {
|
|
3521
|
-
console.log(
|
|
3692
|
+
console.log(import_chalk11.default.bold("\nEnvelope (pre-send):"));
|
|
3522
3693
|
console.log(formatJson(envelope));
|
|
3523
3694
|
}
|
|
3524
3695
|
try {
|
|
@@ -3526,7 +3697,7 @@ async function sendDelegationEnvelope(args) {
|
|
|
3526
3697
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
3527
3698
|
return result;
|
|
3528
3699
|
} catch (err) {
|
|
3529
|
-
if (err instanceof ApiError && (0,
|
|
3700
|
+
if (err instanceof ApiError && (0, import_sdk13.isPostCommitErrorCode)(err.payload.code)) {
|
|
3530
3701
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
3531
3702
|
}
|
|
3532
3703
|
throw err;
|
|
@@ -3548,7 +3719,7 @@ async function resolveDelegationRefs(cmdName, api, signer, args) {
|
|
|
3548
3719
|
);
|
|
3549
3720
|
}
|
|
3550
3721
|
let recipientDid;
|
|
3551
|
-
if (args.action ===
|
|
3722
|
+
if (args.action === import_sdk13.DelegationActions.CANCEL) {
|
|
3552
3723
|
const firstEvents = await api.listEvents(args.relationshipId, signer, { since: 0, limit: 1 });
|
|
3553
3724
|
const handshake = firstEvents[0];
|
|
3554
3725
|
if (!handshake) {
|
|
@@ -3573,7 +3744,7 @@ async function resolveDelegationRefs(cmdName, api, signer, args) {
|
|
|
3573
3744
|
async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
3574
3745
|
const log = args.log ?? ((line) => console.log(line));
|
|
3575
3746
|
log(
|
|
3576
|
-
|
|
3747
|
+
import_chalk11.default.dim(
|
|
3577
3748
|
`
|
|
3578
3749
|
[--wait-for-lock] delegation ${args.delegationId} is awaiting on-chain lock confirmation; polling until ready (interval=${args.intervalSec}s timeout=${args.timeoutSec}s)`
|
|
3579
3750
|
)
|
|
@@ -3588,7 +3759,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3588
3759
|
after = page[page.length - 1].id;
|
|
3589
3760
|
}
|
|
3590
3761
|
};
|
|
3591
|
-
const outcome = await (0,
|
|
3762
|
+
const outcome = await (0, import_sdk13.pollUntil)({
|
|
3592
3763
|
fetch: fetchRow,
|
|
3593
3764
|
// Match on either "row not found at all" OR "state moved
|
|
3594
3765
|
// past pending_lock_finalization". The post-poll branch
|
|
@@ -3598,7 +3769,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3598
3769
|
// rows return cleanly. Polling on null would loop pointlessly
|
|
3599
3770
|
// until the deadline fires and surface a misleading "timed
|
|
3600
3771
|
// out" message for what's actually a wrong-id problem.
|
|
3601
|
-
predicate: (row2) => row2 === null || row2.state !==
|
|
3772
|
+
predicate: (row2) => row2 === null || row2.state !== import_sdk13.DelegationStates.PENDING_LOCK_FINALIZATION,
|
|
3602
3773
|
intervalMs: args.intervalSec * 1e3,
|
|
3603
3774
|
timeoutMs: args.timeoutSec * 1e3,
|
|
3604
3775
|
// Swallow ONLY transient errors. A 4xx during the poll is a
|
|
@@ -3612,7 +3783,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3612
3783
|
if (err instanceof ApiError && err.status >= 400 && err.status < 500) {
|
|
3613
3784
|
throw err;
|
|
3614
3785
|
}
|
|
3615
|
-
log(
|
|
3786
|
+
log(import_chalk11.default.dim(` poll: transient fetch error (${err instanceof Error ? err.message : String(err)})`));
|
|
3616
3787
|
}
|
|
3617
3788
|
});
|
|
3618
3789
|
if (outcome.kind === "timeout") {
|
|
@@ -3629,12 +3800,12 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3629
3800
|
`${cmdName}: delegation ${args.delegationId} disappeared from relationship ${args.relationshipId} during --wait-for-lock pre-flight. Re-check the delegation id with \`heyarp delegations ${args.relationshipId}\`.`
|
|
3630
3801
|
);
|
|
3631
3802
|
}
|
|
3632
|
-
if (row.state !==
|
|
3803
|
+
if (row.state !== import_sdk13.DelegationStates.OFFERED) {
|
|
3633
3804
|
throw new Error(
|
|
3634
3805
|
`${cmdName}: delegation ${args.delegationId} transitioned to '${row.state}' while waiting for on-chain lock confirmation; cannot ${args.action}. Re-read the delegation timeline with \`heyarp delegations ${args.relationshipId}\` to see the latest state.`
|
|
3635
3806
|
);
|
|
3636
3807
|
}
|
|
3637
|
-
log(
|
|
3808
|
+
log(import_chalk11.default.dim(`[--wait-for-lock] delegation ${args.delegationId} ready (state=${row.state}); proceeding with ${args.action}.`));
|
|
3638
3809
|
return row;
|
|
3639
3810
|
}
|
|
3640
3811
|
function parseLockWaitTimeout(cmdName, raw) {
|
|
@@ -3660,12 +3831,12 @@ function parseLockWaitInterval(cmdName, raw) {
|
|
|
3660
3831
|
return n;
|
|
3661
3832
|
}
|
|
3662
3833
|
function printIngestResult(result) {
|
|
3663
|
-
console.log(
|
|
3664
|
-
console.log(`${
|
|
3665
|
-
console.log(`${
|
|
3666
|
-
console.log(`${
|
|
3667
|
-
console.log(`${
|
|
3668
|
-
console.log(`${
|
|
3834
|
+
console.log(import_chalk11.default.green("\nDelivered."));
|
|
3835
|
+
console.log(`${import_chalk11.default.bold("Event id")}: ${import_chalk11.default.cyan(result.eventId)}`);
|
|
3836
|
+
console.log(`${import_chalk11.default.bold("Relationship id")}: ${import_chalk11.default.cyan(result.relationshipId)}`);
|
|
3837
|
+
console.log(`${import_chalk11.default.bold("Chain index")}: ${import_chalk11.default.cyan(String(result.relationshipEventIndex))}`);
|
|
3838
|
+
console.log(`${import_chalk11.default.bold("Server timestamp")}: ${import_chalk11.default.cyan(result.serverTimestamp)}`);
|
|
3839
|
+
console.log(`${import_chalk11.default.bold("Server event hash")}: ${import_chalk11.default.cyan(result.serverEventHash)}`);
|
|
3669
3840
|
}
|
|
3670
3841
|
function parseOfferTerms(cmdName, opts) {
|
|
3671
3842
|
const out = {};
|
|
@@ -3689,7 +3860,7 @@ function parseOfferTerms(cmdName, opts) {
|
|
|
3689
3860
|
if (opts.amount) {
|
|
3690
3861
|
out.amount = opts.amount;
|
|
3691
3862
|
if (!opts.currency) {
|
|
3692
|
-
throw new Error(`${cmdName}: --amount requires --currency. Shorthand: ${
|
|
3863
|
+
throw new Error(`${cmdName}: --amount requires --currency. Shorthand: ${import_sdk13.WELL_KNOWN_ASSET_KEYS.join(", ")}, or raw CAIP-19 + --currency-decimals.`);
|
|
3693
3864
|
}
|
|
3694
3865
|
out.currency = buildAssetIdentifier(cmdName, DELEGATION_CURRENCY_FLAGS, opts.currency, opts.currencyDecimals, opts.currencySymbol);
|
|
3695
3866
|
} else if (opts.currency) {
|
|
@@ -3712,7 +3883,7 @@ function resolveOfferDelegationId(rawCliId, escrow) {
|
|
|
3712
3883
|
cliId = rawCliId.toLowerCase();
|
|
3713
3884
|
}
|
|
3714
3885
|
if (escrow === void 0) {
|
|
3715
|
-
return cliId ?? (0,
|
|
3886
|
+
return cliId ?? (0, import_sdk13.uuidV4)();
|
|
3716
3887
|
}
|
|
3717
3888
|
if (escrow.delegationIdFromLock !== void 0) {
|
|
3718
3889
|
const fileId = escrow.delegationIdFromLock;
|
|
@@ -3742,10 +3913,10 @@ function collectRepeated(value, previous) {
|
|
|
3742
3913
|
}
|
|
3743
3914
|
function parseDeclineReason(cmdName, raw) {
|
|
3744
3915
|
if (raw === void 0 || raw === "") {
|
|
3745
|
-
throw new Error(`${cmdName}: --reason is required when declining (one of: ${
|
|
3916
|
+
throw new Error(`${cmdName}: --reason is required when declining (one of: ${import_sdk13.DECLINE_REASONS.join(", ")})`);
|
|
3746
3917
|
}
|
|
3747
|
-
if (!(0,
|
|
3748
|
-
throw new Error(`${cmdName}: --reason must be one of ${
|
|
3918
|
+
if (!(0, import_sdk13.isDeclineReason)(raw)) {
|
|
3919
|
+
throw new Error(`${cmdName}: --reason must be one of ${import_sdk13.DECLINE_REASONS.join(", ")} (got '${raw}')`);
|
|
3749
3920
|
}
|
|
3750
3921
|
return raw;
|
|
3751
3922
|
}
|
|
@@ -3760,10 +3931,10 @@ function parseReasonDetail(cmdName, raw) {
|
|
|
3760
3931
|
return raw;
|
|
3761
3932
|
}
|
|
3762
3933
|
function buildAssetIdentifier(cmdName, labels, rawCurrency, rawDecimals, rawSymbol) {
|
|
3763
|
-
const resolved = (0,
|
|
3934
|
+
const resolved = (0, import_sdk13.resolveAsset)(rawCurrency);
|
|
3764
3935
|
if (!resolved) {
|
|
3765
3936
|
throw new Error(
|
|
3766
|
-
`${cmdName}: ${labels.currencyFlag} '${rawCurrency}' is not a known shorthand or a valid CAIP-19 string. Shorthand: ${
|
|
3937
|
+
`${cmdName}: ${labels.currencyFlag} '${rawCurrency}' is not a known shorthand or a valid CAIP-19 string. Shorthand: ${import_sdk13.WELL_KNOWN_ASSET_KEYS.join(", ")}. Or pass a raw CAIP-19 id (e.g. "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/spl:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") with ${labels.decimalsFlag}.`
|
|
3767
3938
|
);
|
|
3768
3939
|
}
|
|
3769
3940
|
let decimals = resolved.decimals;
|
|
@@ -3772,20 +3943,20 @@ function buildAssetIdentifier(cmdName, labels, rawCurrency, rawDecimals, rawSymb
|
|
|
3772
3943
|
throw new Error(`${cmdName}: ${labels.currencyFlag} is a raw CAIP-19 string; ${labels.decimalsFlag} (0-18) is required to convert amounts to base units.`);
|
|
3773
3944
|
}
|
|
3774
3945
|
const parsed = Number(rawDecimals);
|
|
3775
|
-
if (!Number.isInteger(parsed) || parsed <
|
|
3946
|
+
if (!Number.isInteger(parsed) || parsed < import_sdk13.ASSET_DECIMALS_MIN || parsed > import_sdk13.ASSET_DECIMALS_MAX) {
|
|
3776
3947
|
throw new Error(`${cmdName}: ${labels.decimalsFlag} must be an integer in [0, 18] (got '${rawDecimals}').`);
|
|
3777
3948
|
}
|
|
3778
3949
|
decimals = parsed;
|
|
3779
3950
|
} else if (rawDecimals !== void 0) {
|
|
3780
3951
|
const parsed = Number(rawDecimals);
|
|
3781
|
-
if (!Number.isInteger(parsed) || parsed <
|
|
3952
|
+
if (!Number.isInteger(parsed) || parsed < import_sdk13.ASSET_DECIMALS_MIN || parsed > import_sdk13.ASSET_DECIMALS_MAX) {
|
|
3782
3953
|
throw new Error(`${cmdName}: ${labels.decimalsFlag} must be an integer in [0, 18] (got '${rawDecimals}').`);
|
|
3783
3954
|
}
|
|
3784
3955
|
decimals = parsed;
|
|
3785
3956
|
}
|
|
3786
3957
|
let symbol = resolved.symbol;
|
|
3787
3958
|
if (rawSymbol !== void 0) {
|
|
3788
|
-
if (rawSymbol.length <
|
|
3959
|
+
if (rawSymbol.length < import_sdk13.ASSET_SYMBOL_MIN_LEN || rawSymbol.length > import_sdk13.ASSET_SYMBOL_MAX_LEN) {
|
|
3789
3960
|
throw new Error(`${cmdName}: ${labels.symbolFlag} must be 1-16 chars (got length ${rawSymbol.length}).`);
|
|
3790
3961
|
}
|
|
3791
3962
|
symbol = rawSymbol;
|
|
@@ -3799,10 +3970,10 @@ var DELEGATION_CURRENCY_FLAGS = {
|
|
|
3799
3970
|
};
|
|
3800
3971
|
|
|
3801
3972
|
// src/commands/delegations.ts
|
|
3802
|
-
var
|
|
3803
|
-
var
|
|
3973
|
+
var import_sdk14 = require("@heyanon-arp/sdk");
|
|
3974
|
+
var import_chalk12 = __toESM(require("chalk"));
|
|
3804
3975
|
init_api();
|
|
3805
|
-
var ALLOWED_STATES = /* @__PURE__ */ new Set([
|
|
3976
|
+
var ALLOWED_STATES = /* @__PURE__ */ new Set([import_sdk14.DelegationStates.OFFERED, import_sdk14.DelegationStates.ACCEPTED, import_sdk14.DelegationStates.DECLINED, import_sdk14.DelegationStates.CANCELED]);
|
|
3806
3977
|
function registerDelegationsCommand(root) {
|
|
3807
3978
|
root.command("delegations").description("List delegations for a relationship (one row per delegationId, oldest-first)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--state <s>", "Filter by exact state (offered|accepted|declined|canceled)").option("--after <id>", "Cursor: pass the previous page's last `id` to fetch the next page").option("--limit <n>", "Max rows to return (1..100)", "20").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option(
|
|
3808
3979
|
"--verbose",
|
|
@@ -3822,9 +3993,9 @@ async function runDelegations(relationshipId, opts) {
|
|
|
3822
3993
|
const state = parseState(opts.state);
|
|
3823
3994
|
const api = new ArpApiClient(opts.server);
|
|
3824
3995
|
const sender = resolveSenderAgent("delegations", opts.server, opts.fromDid, opts.from);
|
|
3825
|
-
progress(opts.json,
|
|
3826
|
-
progress(opts.json,
|
|
3827
|
-
progress(opts.json,
|
|
3996
|
+
progress(opts.json, import_chalk12.default.dim(`Server: ${api.serverUrl}`));
|
|
3997
|
+
progress(opts.json, import_chalk12.default.dim(`Signer: ${sender.did}`));
|
|
3998
|
+
progress(opts.json, import_chalk12.default.dim(`Relationship: ${relationshipId}`));
|
|
3828
3999
|
const query = { limit };
|
|
3829
4000
|
if (state) query.state = state;
|
|
3830
4001
|
if (opts.after) query.after = opts.after;
|
|
@@ -3835,7 +4006,7 @@ async function runDelegations(relationshipId, opts) {
|
|
|
3835
4006
|
return;
|
|
3836
4007
|
}
|
|
3837
4008
|
if (rows.length === 0) {
|
|
3838
|
-
console.log(
|
|
4009
|
+
console.log(import_chalk12.default.dim("\n(no delegations for this relationship)"));
|
|
3839
4010
|
return;
|
|
3840
4011
|
}
|
|
3841
4012
|
console.log("");
|
|
@@ -3851,19 +4022,19 @@ async function runDelegations(relationshipId, opts) {
|
|
|
3851
4022
|
}));
|
|
3852
4023
|
}
|
|
3853
4024
|
const lastId = rows[rows.length - 1].id;
|
|
3854
|
-
console.log(
|
|
4025
|
+
console.log(import_chalk12.default.dim(`
|
|
3855
4026
|
${rows.length} delegation row(s). Paginate with --after ${lastId}.`));
|
|
3856
4027
|
}
|
|
3857
4028
|
function formatDelegationLine(d, selfDid, opts = {}) {
|
|
3858
|
-
const idHead_ =
|
|
4029
|
+
const idHead_ = import_chalk12.default.bold(opts.fullIds ? d.delegationId : idHead(d.delegationId));
|
|
3859
4030
|
const state = colorState(d.state).padEnd(stateColumnWidth());
|
|
3860
|
-
const offerer = d.offererDid === selfDid ?
|
|
4031
|
+
const offerer = d.offererDid === selfDid ? import_chalk12.default.bold("me") : import_chalk12.default.dim(opts.fullIds ? d.offererDid : didHead(d.offererDid));
|
|
3861
4032
|
const amount = formatAmount(d);
|
|
3862
|
-
const title = d.title ?
|
|
4033
|
+
const title = d.title ? import_chalk12.default.dim(`"${truncate2(d.title, 40)}"`) : import_chalk12.default.dim("(no title)");
|
|
3863
4034
|
let declineSuffix = "";
|
|
3864
|
-
if (d.state ===
|
|
4035
|
+
if (d.state === import_sdk14.DelegationStates.DECLINED && d.declineReason) {
|
|
3865
4036
|
const detail = d.declineReasonDetail ? `: ${truncate2(d.declineReasonDetail, 40)}` : "";
|
|
3866
|
-
declineSuffix = ` ${
|
|
4037
|
+
declineSuffix = ` ${import_chalk12.default.dim(`(reason: ${d.declineReason}${detail})`)}`;
|
|
3867
4038
|
}
|
|
3868
4039
|
return `${idHead_} ${state} ${offerer} ${amount} ${title}${declineSuffix}`;
|
|
3869
4040
|
}
|
|
@@ -3876,35 +4047,35 @@ function colorState(s) {
|
|
|
3876
4047
|
// returns `undefined` and `formatDelegationLine` crashes with
|
|
3877
4048
|
// `TypeError: Cannot read properties of undefined (reading
|
|
3878
4049
|
// 'padEnd')` on any listing containing such a row.
|
|
3879
|
-
case
|
|
3880
|
-
return
|
|
3881
|
-
case
|
|
3882
|
-
return
|
|
3883
|
-
case
|
|
3884
|
-
return
|
|
4050
|
+
case import_sdk14.DelegationStates.OFFERED:
|
|
4051
|
+
return import_chalk12.default.yellow("offered");
|
|
4052
|
+
case import_sdk14.DelegationStates.PENDING_LOCK_FINALIZATION:
|
|
4053
|
+
return import_chalk12.default.yellow("pending_lock");
|
|
4054
|
+
case import_sdk14.DelegationStates.ACCEPTED:
|
|
4055
|
+
return import_chalk12.default.green("accepted");
|
|
3885
4056
|
// The on-chain escrow lock is confirmed. Distinct branch so a
|
|
3886
4057
|
// LOCKED row renders without hitting the defensive fallback
|
|
3887
4058
|
// (which would otherwise echo the raw state).
|
|
3888
|
-
case
|
|
3889
|
-
return
|
|
3890
|
-
case
|
|
3891
|
-
return
|
|
3892
|
-
case
|
|
3893
|
-
return
|
|
4059
|
+
case import_sdk14.DelegationStates.LOCKED:
|
|
4060
|
+
return import_chalk12.default.green("locked");
|
|
4061
|
+
case import_sdk14.DelegationStates.DECLINED:
|
|
4062
|
+
return import_chalk12.default.red("declined");
|
|
4063
|
+
case import_sdk14.DelegationStates.CANCELED:
|
|
4064
|
+
return import_chalk12.default.dim("canceled");
|
|
3894
4065
|
// Terminal escrow outcomes: completed = payee paid;
|
|
3895
4066
|
// failed = create_lock never landed; refunded = funds returned
|
|
3896
4067
|
// to the buyer (work expired / dispute closed);
|
|
3897
4068
|
// dispute_resolved = operator ruled.
|
|
3898
|
-
case
|
|
3899
|
-
return
|
|
3900
|
-
case
|
|
3901
|
-
return
|
|
3902
|
-
case
|
|
3903
|
-
return
|
|
3904
|
-
case
|
|
3905
|
-
return
|
|
3906
|
-
case
|
|
3907
|
-
return
|
|
4069
|
+
case import_sdk14.DelegationStates.COMPLETED:
|
|
4070
|
+
return import_chalk12.default.green("completed");
|
|
4071
|
+
case import_sdk14.DelegationStates.FAILED:
|
|
4072
|
+
return import_chalk12.default.red("failed");
|
|
4073
|
+
case import_sdk14.DelegationStates.REFUNDED:
|
|
4074
|
+
return import_chalk12.default.red("refunded");
|
|
4075
|
+
case import_sdk14.DelegationStates.DISPUTING:
|
|
4076
|
+
return import_chalk12.default.yellow("disputing");
|
|
4077
|
+
case import_sdk14.DelegationStates.DISPUTE_RESOLVED:
|
|
4078
|
+
return import_chalk12.default.red("dispute_resolved");
|
|
3908
4079
|
default: {
|
|
3909
4080
|
const _exhaustive = s;
|
|
3910
4081
|
void _exhaustive;
|
|
@@ -3916,9 +4087,9 @@ function stateColumnWidth() {
|
|
|
3916
4087
|
return 12;
|
|
3917
4088
|
}
|
|
3918
4089
|
function formatAmount(d) {
|
|
3919
|
-
if (!d.amount) return
|
|
4090
|
+
if (!d.amount) return import_chalk12.default.dim("(no amount)");
|
|
3920
4091
|
const currency = d.currency ? d.currency.symbol ?? d.currency.assetId : "?";
|
|
3921
|
-
return
|
|
4092
|
+
return import_chalk12.default.cyan(`${d.amount} ${currency}`);
|
|
3922
4093
|
}
|
|
3923
4094
|
function idHead(id) {
|
|
3924
4095
|
if (id.length <= 12) return id;
|
|
@@ -3949,7 +4120,7 @@ function parseLimit2(raw) {
|
|
|
3949
4120
|
}
|
|
3950
4121
|
|
|
3951
4122
|
// src/commands/did-doc.ts
|
|
3952
|
-
var
|
|
4123
|
+
var import_sdk15 = require("@heyanon-arp/sdk");
|
|
3953
4124
|
init_api();
|
|
3954
4125
|
function registerDidDocCommand(root) {
|
|
3955
4126
|
root.command("did-doc").description(
|
|
@@ -3958,7 +4129,7 @@ function registerDidDocCommand(root) {
|
|
|
3958
4129
|
"--field <path>",
|
|
3959
4130
|
"Extract a single value via a dotted path. Supports object property access (`id`), numeric array indexes (`verificationMethod.0`), and `#fragment` array selectors that match a verification-method or service entry by its `id` suffix (`verificationMethod.#settlement.publicKeyMultibase`). Two well-known shortcuts skip the path entirely AND strip the multibase prefix: `settlementPublicKey` / `identityPublicKey` emit the raw base58 pubkey ready for flags like `--recipient-pubkey`. Scalar values (string / number / boolean) emit raw to stdout for shell composition (`KEY=$(heyarp did-doc ... --field ...)`); objects / arrays emit as pretty-printed JSON. Mutually exclusive with `--json` since `--field` already controls the shape."
|
|
3960
4131
|
).action(async (did, opts) => {
|
|
3961
|
-
if (!(0,
|
|
4132
|
+
if (!(0, import_sdk15.isValidDid)(did)) {
|
|
3962
4133
|
throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
|
|
3963
4134
|
}
|
|
3964
4135
|
if (opts.json && opts.field !== void 0) {
|
|
@@ -4069,134 +4240,8 @@ function describeShape(value) {
|
|
|
4069
4240
|
return typeof value;
|
|
4070
4241
|
}
|
|
4071
4242
|
|
|
4072
|
-
// src/commands/doctor.ts
|
|
4073
|
-
var import_sdk15 = require("@heyanon-arp/sdk");
|
|
4074
|
-
var import_chalk11 = __toESM(require("chalk"));
|
|
4075
|
-
init_api();
|
|
4076
|
-
function registerDoctorCommand(root) {
|
|
4077
|
-
root.command("doctor").description("Liveness probe for a counterparty: resolve DID document + read protocol activity. No auth.").argument("<did>", "did:arp:<base58btc> of the agent to probe").option("--server <url>", "Override ARP server base URL").option("--json", "Machine-readable: single JSON object on stdout. Pipe-safe.", false).action(async (did, opts) => {
|
|
4078
|
-
await runDoctor(did, opts);
|
|
4079
|
-
});
|
|
4080
|
-
}
|
|
4081
|
-
var LISTENING_THRESHOLD_SECONDS = 15 * 60;
|
|
4082
|
-
async function runDoctor(did, opts) {
|
|
4083
|
-
if (!(0, import_sdk15.isValidDid)(did)) {
|
|
4084
|
-
throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
|
|
4085
|
-
}
|
|
4086
|
-
const api = new ArpApiClient(opts.server);
|
|
4087
|
-
const result = await probe(api, did);
|
|
4088
|
-
if (opts.json) {
|
|
4089
|
-
console.log(JSON.stringify(result));
|
|
4090
|
-
} else {
|
|
4091
|
-
console.log(formatDoctorReport(result));
|
|
4092
|
-
}
|
|
4093
|
-
if (result.verdict !== "LISTENING") {
|
|
4094
|
-
process.exitCode = 1;
|
|
4095
|
-
}
|
|
4096
|
-
}
|
|
4097
|
-
async function probe(api, did) {
|
|
4098
|
-
const base = {
|
|
4099
|
-
did,
|
|
4100
|
-
server: api.serverUrl,
|
|
4101
|
-
didDocument: { found: false },
|
|
4102
|
-
verdict: "UNKNOWN",
|
|
4103
|
-
reason: ""
|
|
4104
|
-
};
|
|
4105
|
-
let doc;
|
|
4106
|
-
try {
|
|
4107
|
-
doc = await api.getDidDocument(did);
|
|
4108
|
-
} catch (err) {
|
|
4109
|
-
if (err instanceof ApiError && err.status === 404) {
|
|
4110
|
-
return { ...base, verdict: "UNKNOWN", reason: "DID not registered on this server" };
|
|
4111
|
-
}
|
|
4112
|
-
return { ...base, verdict: "UNKNOWN", reason: `DID document fetch failed: ${err.message}` };
|
|
4113
|
-
}
|
|
4114
|
-
base.didDocument = { found: true, registeredAt: doc.metadata?.registered_at };
|
|
4115
|
-
let activity;
|
|
4116
|
-
try {
|
|
4117
|
-
const summary = await api.getActivitySummary(did);
|
|
4118
|
-
const asOfMs = new Date(summary.asOf).getTime();
|
|
4119
|
-
const lastMs = summary.lastEventAt ? new Date(summary.lastEventAt).getTime() : null;
|
|
4120
|
-
const ageSeconds = lastMs !== null ? Math.max(0, Math.floor((asOfMs - lastMs) / 1e3)) : null;
|
|
4121
|
-
const seenMs = summary.lastSeenAt ? new Date(summary.lastSeenAt).getTime() : null;
|
|
4122
|
-
const seenAgeSeconds = seenMs !== null ? Math.max(0, Math.floor((asOfMs - seenMs) / 1e3)) : null;
|
|
4123
|
-
activity = {
|
|
4124
|
-
lastEventAt: summary.lastEventAt,
|
|
4125
|
-
asOf: summary.asOf,
|
|
4126
|
-
ageSeconds,
|
|
4127
|
-
lastSeenAt: summary.lastSeenAt ?? null,
|
|
4128
|
-
seenAgeSeconds,
|
|
4129
|
-
inboxStreamActive: summary.inboxStreamActive
|
|
4130
|
-
};
|
|
4131
|
-
} catch {
|
|
4132
|
-
return { ...base, verdict: "UNKNOWN", reason: "DID resolves but the server does not expose an activity summary \u2014 cannot assess liveness" };
|
|
4133
|
-
}
|
|
4134
|
-
const recentlyActive = activity.ageSeconds !== null && activity.ageSeconds !== void 0 && activity.ageSeconds <= LISTENING_THRESHOLD_SECONDS;
|
|
4135
|
-
const recentlySeen = activity.seenAgeSeconds !== null && activity.seenAgeSeconds !== void 0 && activity.seenAgeSeconds <= LISTENING_THRESHOLD_SECONDS;
|
|
4136
|
-
const inboxStreamActive = activity.inboxStreamActive === true;
|
|
4137
|
-
const result = { ...base, activity };
|
|
4138
|
-
if (inboxStreamActive) {
|
|
4139
|
-
return {
|
|
4140
|
-
...result,
|
|
4141
|
-
verdict: "LISTENING",
|
|
4142
|
-
reason: "inbox-stream attached (active SSE subscription on the central server) \u2014 protocol-reachable; worker is actively waiting for envelopes"
|
|
4143
|
-
};
|
|
4144
|
-
}
|
|
4145
|
-
if (recentlySeen) {
|
|
4146
|
-
const seenStr = activity.seenAgeSeconds !== void 0 && activity.seenAgeSeconds !== null ? `${activity.seenAgeSeconds}s ago` : "recently";
|
|
4147
|
-
return {
|
|
4148
|
-
...result,
|
|
4149
|
-
verdict: "LISTENING",
|
|
4150
|
-
reason: `recently seen (signed API request ${seenStr}) \u2014 agent is polling the server (cron-mode worker)`
|
|
4151
|
-
};
|
|
4152
|
-
}
|
|
4153
|
-
if (recentlyActive) {
|
|
4154
|
-
const ageStr = activity.ageSeconds !== void 0 && activity.ageSeconds !== null ? `${activity.ageSeconds}s ago` : "recently";
|
|
4155
|
-
return {
|
|
4156
|
-
...result,
|
|
4157
|
-
verdict: "LISTENING",
|
|
4158
|
-
reason: `inbox-active (last event ${ageStr}) \u2014 protocol-reachable via the central ARP server`
|
|
4159
|
-
};
|
|
4160
|
-
}
|
|
4161
|
-
const ageNote = activity.lastEventAt === null ? "no events ever" : `last event ${activity.ageSeconds}s ago`;
|
|
4162
|
-
const seenNote = activity.lastSeenAt === null || activity.lastSeenAt === void 0 ? "never seen polling" : `last seen ${activity.seenAgeSeconds}s ago`;
|
|
4163
|
-
return { ...result, verdict: "DORMANT", reason: `no open inbox stream, ${seenNote}, and ${ageNote} \u2014 agent appears idle (cross-check before relying on it)` };
|
|
4164
|
-
}
|
|
4165
|
-
function formatDoctorReport(r) {
|
|
4166
|
-
const lines = [];
|
|
4167
|
-
lines.push(`${import_chalk11.default.dim("Server:")} ${r.server}`);
|
|
4168
|
-
lines.push(`${import_chalk11.default.dim("Target DID:")} ${r.did}`);
|
|
4169
|
-
if (!r.didDocument.found) {
|
|
4170
|
-
lines.push(`${import_chalk11.default.dim("DID doc:")} ${import_chalk11.default.red("\u2717")} not found`);
|
|
4171
|
-
} else {
|
|
4172
|
-
const registered = r.didDocument.registeredAt ? ` (registered ${r.didDocument.registeredAt})` : "";
|
|
4173
|
-
lines.push(`${import_chalk11.default.dim("DID doc:")} ${import_chalk11.default.green("\u2713")} resolved${registered}`);
|
|
4174
|
-
}
|
|
4175
|
-
if (r.activity) {
|
|
4176
|
-
if (r.activity.lastEventAt === null) {
|
|
4177
|
-
lines.push(`${import_chalk11.default.dim("Activity:")} ${import_chalk11.default.dim("(no events ever \u2014 fresh agent)")}`);
|
|
4178
|
-
} else {
|
|
4179
|
-
const ageMin = r.activity.ageSeconds !== null ? Math.floor(r.activity.ageSeconds / 60) : null;
|
|
4180
|
-
const ageStr = ageMin !== null && ageMin > 0 ? `${ageMin}m ago` : `${r.activity.ageSeconds}s ago`;
|
|
4181
|
-
lines.push(`${import_chalk11.default.dim("Activity:")} last event ${ageStr} (${r.activity.lastEventAt})`);
|
|
4182
|
-
}
|
|
4183
|
-
if (r.activity.lastSeenAt !== null && r.activity.lastSeenAt !== void 0) {
|
|
4184
|
-
const seenMin = r.activity.seenAgeSeconds !== null && r.activity.seenAgeSeconds !== void 0 ? Math.floor(r.activity.seenAgeSeconds / 60) : null;
|
|
4185
|
-
const seenStr = seenMin !== null && seenMin > 0 ? `${seenMin}m ago` : `${r.activity.seenAgeSeconds}s ago`;
|
|
4186
|
-
lines.push(`${import_chalk11.default.dim("Last seen:")} signed request ${seenStr} (${r.activity.lastSeenAt})`);
|
|
4187
|
-
}
|
|
4188
|
-
if (r.activity.inboxStreamActive === true) {
|
|
4189
|
-
lines.push(`${import_chalk11.default.dim("Inbox SSE:")} ${import_chalk11.default.green("\u2713")} active subscription on the central server`);
|
|
4190
|
-
}
|
|
4191
|
-
}
|
|
4192
|
-
const verdictColor = r.verdict === "LISTENING" ? import_chalk11.default.green : r.verdict === "DORMANT" ? import_chalk11.default.red : import_chalk11.default.yellow;
|
|
4193
|
-
lines.push("");
|
|
4194
|
-
lines.push(`${import_chalk11.default.bold("Verdict:")} ${verdictColor(r.verdict)} \u2014 ${r.reason}`);
|
|
4195
|
-
return lines.join("\n");
|
|
4196
|
-
}
|
|
4197
|
-
|
|
4198
4243
|
// src/commands/envelope.ts
|
|
4199
|
-
var
|
|
4244
|
+
var import_chalk13 = __toESM(require("chalk"));
|
|
4200
4245
|
init_api();
|
|
4201
4246
|
function registerEnvelopeCommand(root) {
|
|
4202
4247
|
root.command("envelope").description("Fetch one canonical envelope by eventId \u2014 full body for inspection (signed read)").argument("<event-id>", "Event UUID \u2014 copy from `heyarp inbox`, `heyarp events`, or a counterparty citation").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--json", "Machine-readable: emit only the envelope JSON object on stdout (no prelude, no chalk). Pipe-safe.", false).action(async (eventId, opts) => {
|
|
@@ -4207,9 +4252,9 @@ async function runEnvelope(eventId, opts) {
|
|
|
4207
4252
|
const api = new ArpApiClient(opts.server);
|
|
4208
4253
|
const sender = resolveSenderAgent("envelope", opts.server, opts.fromDid, opts.from);
|
|
4209
4254
|
if (!opts.json) {
|
|
4210
|
-
console.log(
|
|
4211
|
-
console.log(
|
|
4212
|
-
console.log(
|
|
4255
|
+
console.log(import_chalk13.default.dim(`Server: ${api.serverUrl}`));
|
|
4256
|
+
console.log(import_chalk13.default.dim(`Signer: ${sender.did}`));
|
|
4257
|
+
console.log(import_chalk13.default.dim(`Event: ${eventId}`));
|
|
4213
4258
|
}
|
|
4214
4259
|
const signer = makeSigner(sender);
|
|
4215
4260
|
const event = await api.getEvent(sender.did, eventId, signer);
|
|
@@ -4218,24 +4263,24 @@ async function runEnvelope(eventId, opts) {
|
|
|
4218
4263
|
return;
|
|
4219
4264
|
}
|
|
4220
4265
|
console.log("");
|
|
4221
|
-
console.log(
|
|
4266
|
+
console.log(import_chalk13.default.bold("Envelope:"));
|
|
4222
4267
|
console.log(formatJson(event));
|
|
4223
4268
|
console.log("");
|
|
4224
4269
|
console.log(formatHints(event));
|
|
4225
4270
|
}
|
|
4226
4271
|
function formatHints(event) {
|
|
4227
4272
|
const lines = [];
|
|
4228
|
-
lines.push(`${
|
|
4229
|
-
lines.push(`${
|
|
4230
|
-
lines.push(`${
|
|
4231
|
-
lines.push(`${
|
|
4273
|
+
lines.push(`${import_chalk13.default.dim("relationshipId:")} ${import_chalk13.default.cyan(event.relationshipId)}`);
|
|
4274
|
+
lines.push(`${import_chalk13.default.dim("serverEventHash:")} ${import_chalk13.default.cyan(event.serverEventHash)}`);
|
|
4275
|
+
lines.push(`${import_chalk13.default.dim("eventId:")} ${import_chalk13.default.cyan(event.eventId)}`);
|
|
4276
|
+
lines.push(`${import_chalk13.default.dim("relationshipEventIndex:")} ${import_chalk13.default.cyan(String(event.relationshipEventIndex))}`);
|
|
4232
4277
|
return lines.join("\n");
|
|
4233
4278
|
}
|
|
4234
4279
|
|
|
4235
4280
|
// src/commands/escrow.ts
|
|
4236
4281
|
var import_sdk17 = require("@heyanon-arp/sdk");
|
|
4237
4282
|
var import_utils2 = require("@noble/hashes/utils");
|
|
4238
|
-
var
|
|
4283
|
+
var import_chalk14 = __toESM(require("chalk"));
|
|
4239
4284
|
init_api();
|
|
4240
4285
|
|
|
4241
4286
|
// src/commands/escrow-actions.ts
|
|
@@ -4252,9 +4297,9 @@ async function setup(cmd, delegationIdArg, opts) {
|
|
|
4252
4297
|
const rpcUrl = resolveRpcUrlStrict(opts, cmd);
|
|
4253
4298
|
const conn = new import_web32.Connection(rpcUrl, "confirmed");
|
|
4254
4299
|
const delegationId = normaliseDelegationId(delegationIdArg);
|
|
4255
|
-
const fetched = await (0,
|
|
4300
|
+
const fetched = await (0, import_sdk10.fetchLockAccount)(conn, programId, delegationId);
|
|
4256
4301
|
if (!fetched) {
|
|
4257
|
-
const lockPda = (0,
|
|
4302
|
+
const lockPda = (0, import_sdk10.deriveLockPda)(programId, (0, import_sdk16.deriveLockId)(delegationId)).toBase58();
|
|
4258
4303
|
throw new Error(
|
|
4259
4304
|
`${cmd}: no on-chain Lock for delegation ${delegationId} (PDA ${lockPda} not found on ${rpcUrl}). Either the buyer hasn't funded yet (delegation fund \u2192 server relays create_lock), or you're pointing at the wrong cluster/program.`
|
|
4260
4305
|
);
|
|
@@ -4346,7 +4391,7 @@ async function acceptHandler(delegationId, opts) {
|
|
|
4346
4391
|
const stake = ctx.lock.workerStakeAtLock;
|
|
4347
4392
|
await preflightLamports(ctx, stake, `the worker stake (${stake} lamports, returned when the lock settles in your favour)`);
|
|
4348
4393
|
progress(ctx.opts.json, `accepting lock ${ctx.lock.lockId.slice(0, 16)}\u2026 \u2014 staking ${stake} lamports from ${ctx.keypair.publicKey.toBase58()}`);
|
|
4349
|
-
const sig = await sendIx(ctx, (0,
|
|
4394
|
+
const sig = await sendIx(ctx, (0, import_sdk10.buildAcceptLockIx)({ programId: ctx.programId, lockId: ctx.lockId, payee: ctx.keypair.publicKey }));
|
|
4350
4395
|
emit(ctx, "accept", sig, { worker_stake: stake.toString() });
|
|
4351
4396
|
}
|
|
4352
4397
|
async function submitWorkHandler(delegationId, opts) {
|
|
@@ -4358,10 +4403,10 @@ async function submitWorkHandler(delegationId, opts) {
|
|
|
4358
4403
|
`escrow submit-work: the work window expired at ${expiryIso(ctx)} \u2014 the chain will reject submit_work and the buyer can claim the escrow back (claim_expired_work). Nothing to salvage on-chain.`
|
|
4359
4404
|
);
|
|
4360
4405
|
}
|
|
4361
|
-
const sig = await sendIx(ctx, (0,
|
|
4406
|
+
const sig = await sendIx(ctx, (0, import_sdk10.buildSubmitWorkIx)({ programId: ctx.programId, lockId: ctx.lockId, payee: ctx.keypair.publicKey }));
|
|
4362
4407
|
let reviewDeadline = null;
|
|
4363
4408
|
try {
|
|
4364
|
-
const fresh = await (0,
|
|
4409
|
+
const fresh = await (0, import_sdk10.fetchLockAccount)(ctx.conn, ctx.programId, ctx.delegationId);
|
|
4365
4410
|
if (fresh && fresh.lock.state === import_sdk16.LockStates.SUBMITTED && fresh.lock.expiry > 0n) {
|
|
4366
4411
|
reviewDeadline = new Date(Number(fresh.lock.expiry) * 1e3).toISOString();
|
|
4367
4412
|
}
|
|
@@ -4396,7 +4441,7 @@ async function claimHandler(delegationId, opts) {
|
|
|
4396
4441
|
);
|
|
4397
4442
|
const sig = await sendIx(
|
|
4398
4443
|
ctx,
|
|
4399
|
-
(0,
|
|
4444
|
+
(0, import_sdk10.buildClaimWorkPaymentIx)({
|
|
4400
4445
|
programId: ctx.programId,
|
|
4401
4446
|
lockId: ctx.lockId,
|
|
4402
4447
|
authority: ctx.keypair.publicKey,
|
|
@@ -4414,7 +4459,7 @@ async function cancelHandler(delegationId, opts) {
|
|
|
4414
4459
|
requireSigner(ctx, "payer", ctx.lock.payer);
|
|
4415
4460
|
const sig = await sendIx(
|
|
4416
4461
|
ctx,
|
|
4417
|
-
(0,
|
|
4462
|
+
(0, import_sdk10.buildCancelLockIx)({
|
|
4418
4463
|
programId: ctx.programId,
|
|
4419
4464
|
lockId: ctx.lockId,
|
|
4420
4465
|
payer: ctx.keypair.publicKey,
|
|
@@ -4432,7 +4477,7 @@ async function claimExpiredHandler(delegationId, opts) {
|
|
|
4432
4477
|
}
|
|
4433
4478
|
const sig = await sendIx(
|
|
4434
4479
|
ctx,
|
|
4435
|
-
(0,
|
|
4480
|
+
(0, import_sdk10.buildClaimExpiredWorkIx)({
|
|
4436
4481
|
programId: ctx.programId,
|
|
4437
4482
|
lockId: ctx.lockId,
|
|
4438
4483
|
payer: ctx.keypair.publicKey,
|
|
@@ -4453,7 +4498,7 @@ async function disputeOpenHandler(delegationId, opts) {
|
|
|
4453
4498
|
const stake = ctx.lock.workerStakeAtLock;
|
|
4454
4499
|
await preflightLamports(ctx, stake, `the dispute stake (${stake} lamports \u2014 returned if the operator rules for you or the dispute times out)`);
|
|
4455
4500
|
progress(ctx.opts.json, `opening dispute \u2014 staking ${stake} lamports; the operator has the dispute window to rule, after that either party can close`);
|
|
4456
|
-
const sig = await sendIx(ctx, (0,
|
|
4501
|
+
const sig = await sendIx(ctx, (0, import_sdk10.buildOpenDisputeIx)({ programId: ctx.programId, lockId: ctx.lockId, payer: ctx.keypair.publicKey }));
|
|
4457
4502
|
emit(ctx, "dispute-open", sig, { buyer_stake: stake.toString() });
|
|
4458
4503
|
}
|
|
4459
4504
|
async function disputeCloseHandler(delegationId, opts) {
|
|
@@ -4470,7 +4515,7 @@ async function disputeCloseHandler(delegationId, opts) {
|
|
|
4470
4515
|
}
|
|
4471
4516
|
const sig = await sendIx(
|
|
4472
4517
|
ctx,
|
|
4473
|
-
(0,
|
|
4518
|
+
(0, import_sdk10.buildCloseDisputeIx)({
|
|
4474
4519
|
programId: ctx.programId,
|
|
4475
4520
|
lockId: ctx.lockId,
|
|
4476
4521
|
authority: ctx.keypair.publicKey,
|
|
@@ -4502,7 +4547,7 @@ async function disputeResolveHandler(delegationId, opts) {
|
|
|
4502
4547
|
const disputeId = Uint8Array.from(Buffer.from(disputeUuid.replace(/-/g, ""), "hex"));
|
|
4503
4548
|
const sig = await sendIx(
|
|
4504
4549
|
ctx,
|
|
4505
|
-
(0,
|
|
4550
|
+
(0, import_sdk10.buildResolveDisputeIx)({
|
|
4506
4551
|
programId: ctx.programId,
|
|
4507
4552
|
lockId: ctx.lockId,
|
|
4508
4553
|
operator: ctx.keypair.publicKey,
|
|
@@ -4522,12 +4567,12 @@ async function showHandler(delegationId, opts) {
|
|
|
4522
4567
|
const rpcUrl = resolveRpcUrlStrict(opts, "escrow show");
|
|
4523
4568
|
const conn = new import_web32.Connection(rpcUrl, "confirmed");
|
|
4524
4569
|
const normalised = normaliseDelegationId(delegationId);
|
|
4525
|
-
const fetched = await (0,
|
|
4570
|
+
const fetched = await (0, import_sdk10.fetchLockAccount)(conn, programId, normalised);
|
|
4526
4571
|
if (!fetched) {
|
|
4527
4572
|
jsonOut({
|
|
4528
4573
|
delegation_id: normalised.slice("del_".length),
|
|
4529
4574
|
lock_exists: false,
|
|
4530
|
-
lock_pda: (0,
|
|
4575
|
+
lock_pda: (0, import_sdk10.deriveLockPda)(programId, (0, import_sdk16.deriveLockId)(normalised)).toBase58(),
|
|
4531
4576
|
rpc_url: redactRpcUrl(rpcUrl)
|
|
4532
4577
|
});
|
|
4533
4578
|
return;
|
|
@@ -4648,7 +4693,7 @@ async function runEscrowInfo(opts) {
|
|
|
4648
4693
|
const api = new ArpApiClient(opts.server);
|
|
4649
4694
|
const status = await api.getEscrowConfig();
|
|
4650
4695
|
if (opts.json) {
|
|
4651
|
-
progress(true,
|
|
4696
|
+
progress(true, import_chalk14.default.dim(`Server: ${api.serverUrl}`));
|
|
4652
4697
|
jsonOut(status);
|
|
4653
4698
|
} else {
|
|
4654
4699
|
console.log(formatEscrowConfigStatus(api.serverUrl, status));
|
|
@@ -4657,35 +4702,35 @@ async function runEscrowInfo(opts) {
|
|
|
4657
4702
|
function formatEscrowConfigStatus(serverUrl, s) {
|
|
4658
4703
|
const lines = [];
|
|
4659
4704
|
const win = (secs) => secs % 3600 === 0 ? `${secs / 3600}h` : secs % 60 === 0 ? `${secs / 60}m` : `${secs}s`;
|
|
4660
|
-
lines.push(`${
|
|
4661
|
-
lines.push(`${
|
|
4662
|
-
lines.push(`${
|
|
4663
|
-
lines.push(`${
|
|
4664
|
-
lines.push(`${
|
|
4705
|
+
lines.push(`${import_chalk14.default.dim("Server:")} ${serverUrl}`);
|
|
4706
|
+
lines.push(`${import_chalk14.default.dim("Program ID:")} ${s.programId}`);
|
|
4707
|
+
lines.push(`${import_chalk14.default.dim("Admin:")} ${s.admin}`);
|
|
4708
|
+
lines.push(`${import_chalk14.default.dim("Treasury:")} ${s.treasury}`);
|
|
4709
|
+
lines.push(`${import_chalk14.default.dim("Paused:")} ${s.paused ? import_chalk14.default.yellow("YES (new locks rejected)") : import_chalk14.default.green("no")}`);
|
|
4665
4710
|
lines.push("");
|
|
4666
|
-
lines.push(
|
|
4667
|
-
lines.push(` ${
|
|
4668
|
-
lines.push(` ${
|
|
4669
|
-
lines.push(` ${
|
|
4711
|
+
lines.push(import_chalk14.default.bold("Windows (rolling deadlines):"));
|
|
4712
|
+
lines.push(` ${import_chalk14.default.dim("work:")} ${win(s.workWindowSecs)} ${import_chalk14.default.dim("(accept \u2192 submit_work)")}`);
|
|
4713
|
+
lines.push(` ${import_chalk14.default.dim("review:")} ${win(s.reviewWindowSecs)} ${import_chalk14.default.dim("(submit_work \u2192 buyer approve / worker self-claim)")}`);
|
|
4714
|
+
lines.push(` ${import_chalk14.default.dim("dispute:")} ${win(s.disputeWindowSecs)} ${import_chalk14.default.dim("(open_dispute \u2192 operator resolve / timeout close)")}`);
|
|
4670
4715
|
lines.push("");
|
|
4671
|
-
lines.push(
|
|
4672
|
-
lines.push(` ${
|
|
4673
|
-
lines.push(` ${
|
|
4716
|
+
lines.push(import_chalk14.default.bold("Stakes:"));
|
|
4717
|
+
lines.push(` ${import_chalk14.default.dim("worker stake:")} ${s.workerStakeLamports} lamports ${import_chalk14.default.dim("(escrowed at accept_lock, returned on completion)")}`);
|
|
4718
|
+
lines.push(` ${import_chalk14.default.dim("operator dispute fee:")} ${s.operatorDisputeFeeLamports} lamports`);
|
|
4674
4719
|
lines.push("");
|
|
4675
|
-
lines.push(
|
|
4720
|
+
lines.push(import_chalk14.default.bold("Protocol fee:"));
|
|
4676
4721
|
if (!s.feeEnabled || s.feeBps === 0) {
|
|
4677
|
-
lines.push(` ${
|
|
4678
|
-
lines.push(` ${
|
|
4679
|
-
lines.push(` ${
|
|
4722
|
+
lines.push(` ${import_chalk14.default.green("DISABLED")}`);
|
|
4723
|
+
lines.push(` ${import_chalk14.default.dim("fee_bps:")} ${s.feeBps}`);
|
|
4724
|
+
lines.push(` ${import_chalk14.default.dim("fee_recipient:")} ${s.feeRecipient}`);
|
|
4680
4725
|
lines.push("");
|
|
4681
|
-
lines.push(
|
|
4726
|
+
lines.push(import_chalk14.default.dim(` New locks will snapshot fee_bps=0 \u2014 payee receives 100% on claim.`));
|
|
4682
4727
|
} else {
|
|
4683
|
-
const
|
|
4684
|
-
lines.push(` ${
|
|
4685
|
-
lines.push(` ${
|
|
4728
|
+
const pct2 = (s.feeBps / 100).toFixed(2);
|
|
4729
|
+
lines.push(` ${import_chalk14.default.yellow("ENABLED")} \u2014 ${pct2}% of payee slice (${s.feeBps} bps)`);
|
|
4730
|
+
lines.push(` ${import_chalk14.default.dim("fee_recipient:")} ${s.feeRecipient}`);
|
|
4686
4731
|
lines.push("");
|
|
4687
|
-
lines.push(
|
|
4688
|
-
lines.push(
|
|
4732
|
+
lines.push(import_chalk14.default.dim(` New locks will snapshot fee_bps=${s.feeBps} onto themselves.`));
|
|
4733
|
+
lines.push(import_chalk14.default.dim(` Existing locks keep their lock-time snapshot \u2014 no retroactive change.`));
|
|
4689
4734
|
}
|
|
4690
4735
|
return lines.join("\n");
|
|
4691
4736
|
}
|
|
@@ -4710,8 +4755,8 @@ async function runDeriveConditionHash(opts) {
|
|
|
4710
4755
|
}
|
|
4711
4756
|
const api = new ArpApiClient(opts.server);
|
|
4712
4757
|
const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid, opts.from);
|
|
4713
|
-
progress(opts.json,
|
|
4714
|
-
progress(opts.json,
|
|
4758
|
+
progress(opts.json, import_chalk14.default.dim(`Server: ${api.serverUrl}`));
|
|
4759
|
+
progress(opts.json, import_chalk14.default.dim(`Signer: ${sender.did}`));
|
|
4715
4760
|
const subset = projectDelegationForHash(cmdName, opts, delegationId);
|
|
4716
4761
|
const hashBytes = (0, import_sdk17.deriveDelegationConditionHash)(subset);
|
|
4717
4762
|
const hex = (0, import_utils2.bytesToHex)(hashBytes);
|
|
@@ -4723,14 +4768,14 @@ async function runDeriveConditionHash(opts) {
|
|
|
4723
4768
|
});
|
|
4724
4769
|
return;
|
|
4725
4770
|
}
|
|
4726
|
-
console.log(
|
|
4727
|
-
console.log(
|
|
4728
|
-
console.log(
|
|
4729
|
-
if (subset.currency !== void 0) console.log(
|
|
4771
|
+
console.log(import_chalk14.default.dim(`Delegation: ${delegationId}`));
|
|
4772
|
+
console.log(import_chalk14.default.dim("Subset hashed:"));
|
|
4773
|
+
console.log(import_chalk14.default.dim(` scopeSummary: ${subset.scopeSummary ?? "(unset)"}`));
|
|
4774
|
+
if (subset.currency !== void 0) console.log(import_chalk14.default.dim(` currency.asset_id: ${subset.currency.asset_id}`));
|
|
4730
4775
|
console.log("");
|
|
4731
|
-
console.log(`${
|
|
4776
|
+
console.log(`${import_chalk14.default.bold("condition_hash:")} ${hex}`);
|
|
4732
4777
|
console.log("");
|
|
4733
|
-
console.log(
|
|
4778
|
+
console.log(import_chalk14.default.dim(`Pass to: heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash ${hex} ...`));
|
|
4734
4779
|
}
|
|
4735
4780
|
function classifyRecoverOutcome(local, server) {
|
|
4736
4781
|
if (local === server) return { kind: "in-sync", value: local };
|
|
@@ -4763,32 +4808,32 @@ async function runRecoverSequence(opts) {
|
|
|
4763
4808
|
applied: opts.apply === true && outcome.kind === "behind"
|
|
4764
4809
|
});
|
|
4765
4810
|
} else {
|
|
4766
|
-
console.log(
|
|
4767
|
-
console.log(
|
|
4811
|
+
console.log(import_chalk14.default.dim(`DID: ${sender.did}`));
|
|
4812
|
+
console.log(import_chalk14.default.dim(`Server: ${api.serverUrl}`));
|
|
4768
4813
|
console.log("");
|
|
4769
|
-
console.log(`${
|
|
4770
|
-
console.log(`${
|
|
4814
|
+
console.log(`${import_chalk14.default.bold("Local lastSenderSequence:")} ${local}`);
|
|
4815
|
+
console.log(`${import_chalk14.default.bold("Server lastSenderSequence:")} ${server}`);
|
|
4771
4816
|
console.log("");
|
|
4772
4817
|
if (outcome.kind === "in-sync") {
|
|
4773
|
-
console.log(
|
|
4818
|
+
console.log(import_chalk14.default.green("\u2713 In sync \u2014 no recovery needed."));
|
|
4774
4819
|
} else if (outcome.kind === "behind") {
|
|
4775
|
-
console.log(
|
|
4820
|
+
console.log(import_chalk14.default.yellow(`\u26A0 Local is BEHIND by ${outcome.drift}. Server has accepted envelopes the CLI didn't classify as post-commit.`));
|
|
4776
4821
|
if (opts.apply) {
|
|
4777
|
-
console.log(
|
|
4822
|
+
console.log(import_chalk14.default.dim("Writing server value to local state..."));
|
|
4778
4823
|
} else {
|
|
4779
|
-
console.log(
|
|
4824
|
+
console.log(import_chalk14.default.dim("Dry-run. Pass --apply to update local state to match server."));
|
|
4780
4825
|
}
|
|
4781
4826
|
} else {
|
|
4782
|
-
console.log(
|
|
4783
|
-
console.log(
|
|
4784
|
-
console.log(
|
|
4785
|
-
console.log(
|
|
4786
|
-
console.log(
|
|
4827
|
+
console.log(import_chalk14.default.red(`\u2717 Local is AHEAD of server by ${outcome.drift}. This should not happen under normal protocol flow.`));
|
|
4828
|
+
console.log(import_chalk14.default.dim("NOT applying \u2014 manual investigation needed. Possible causes:"));
|
|
4829
|
+
console.log(import_chalk14.default.dim(" - Local agents.json edited by hand to a wrong value"));
|
|
4830
|
+
console.log(import_chalk14.default.dim(" - Server data lost / rolled back"));
|
|
4831
|
+
console.log(import_chalk14.default.dim(" - HEYARP_HOME pointed at a wrong account"));
|
|
4787
4832
|
}
|
|
4788
4833
|
}
|
|
4789
4834
|
if (outcome.kind === "behind" && opts.apply) {
|
|
4790
4835
|
updateAgentLocal(opts.server, sender.did, { lastSenderSequence: outcome.server });
|
|
4791
|
-
if (!opts.json) console.log(
|
|
4836
|
+
if (!opts.json) console.log(import_chalk14.default.green(`\u2713 Local lastSenderSequence updated: ${local} \u2192 ${outcome.server}`));
|
|
4792
4837
|
}
|
|
4793
4838
|
if (outcome.kind === "behind" && !opts.apply) process.exitCode = 1;
|
|
4794
4839
|
if (outcome.kind === "ahead") process.exitCode = 2;
|
|
@@ -4796,7 +4841,7 @@ async function runRecoverSequence(opts) {
|
|
|
4796
4841
|
|
|
4797
4842
|
// src/commands/events.ts
|
|
4798
4843
|
var import_sdk18 = require("@heyanon-arp/sdk");
|
|
4799
|
-
var
|
|
4844
|
+
var import_chalk15 = __toESM(require("chalk"));
|
|
4800
4845
|
init_api();
|
|
4801
4846
|
function registerEventsCommand(root) {
|
|
4802
4847
|
root.command("events").description("List events for a relationship (chain order, ascending index)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--since <n>", "Cursor: only events with relationshipEventIndex >= since").option("--limit <n>", "Max events to return (1..100)", "20").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option(
|
|
@@ -4840,9 +4885,9 @@ async function runEvents(relationshipId, opts) {
|
|
|
4840
4885
|
const api = new ArpApiClient(opts.server);
|
|
4841
4886
|
const sender = resolveSenderAgent("events", opts.server, opts.fromDid, opts.from);
|
|
4842
4887
|
if (!opts.json) {
|
|
4843
|
-
console.log(
|
|
4844
|
-
console.log(
|
|
4845
|
-
console.log(
|
|
4888
|
+
console.log(import_chalk15.default.dim(`Server: ${api.serverUrl}`));
|
|
4889
|
+
console.log(import_chalk15.default.dim(`Signer: ${sender.did}`));
|
|
4890
|
+
console.log(import_chalk15.default.dim(`Relationship: ${relationshipId}`));
|
|
4846
4891
|
}
|
|
4847
4892
|
const query = { limit };
|
|
4848
4893
|
if (since !== void 0) query.since = since;
|
|
@@ -4855,7 +4900,7 @@ async function runEvents(relationshipId, opts) {
|
|
|
4855
4900
|
return;
|
|
4856
4901
|
}
|
|
4857
4902
|
if (events.length === 0) {
|
|
4858
|
-
console.log(
|
|
4903
|
+
console.log(import_chalk15.default.dim("\n(no events for this relationship)"));
|
|
4859
4904
|
return;
|
|
4860
4905
|
}
|
|
4861
4906
|
console.log("");
|
|
@@ -4871,20 +4916,20 @@ async function runEvents(relationshipId, opts) {
|
|
|
4871
4916
|
}));
|
|
4872
4917
|
}
|
|
4873
4918
|
const lastIndex = events[events.length - 1].relationshipEventIndex;
|
|
4874
|
-
console.log(
|
|
4919
|
+
console.log(import_chalk15.default.dim(`
|
|
4875
4920
|
${events.length} event(s). Paginate with --since ${lastIndex + 1}.`));
|
|
4876
4921
|
}
|
|
4877
4922
|
function formatEventLine(ev, selfDid, opts = {}) {
|
|
4878
|
-
const idx =
|
|
4923
|
+
const idx = import_chalk15.default.bold(`#${ev.relationshipEventIndex}`);
|
|
4879
4924
|
const eventId = opts.fullIds ? ev.eventId : eventIdHead(ev.eventId);
|
|
4880
4925
|
const type = ev.type.padEnd(20);
|
|
4881
4926
|
const direction = directionLabel(ev, selfDid, opts);
|
|
4882
4927
|
const hash = opts.fullIds ? ev.serverEventHash : hashHead(ev.serverEventHash);
|
|
4883
4928
|
const extra = extraDetail(ev);
|
|
4884
|
-
const tail = extra ? ` ${
|
|
4929
|
+
const tail = extra ? ` ${import_chalk15.default.dim(`(${extra})`)}` : "";
|
|
4885
4930
|
const status = ev.readModelStatus ?? import_sdk18.ReadModelStatuses.MATERIALIZED;
|
|
4886
|
-
const statusGlyph = status === import_sdk18.ReadModelStatuses.REJECTED ? `${
|
|
4887
|
-
return `${statusGlyph}${idx} ${
|
|
4931
|
+
const statusGlyph = status === import_sdk18.ReadModelStatuses.REJECTED ? `${import_chalk15.default.red("\u2717")} ` : " ";
|
|
4932
|
+
return `${statusGlyph}${idx} ${import_chalk15.default.cyan(eventId)} ${type} ${direction} ${import_chalk15.default.cyan(hash)}${tail}`;
|
|
4888
4933
|
}
|
|
4889
4934
|
function eventIdHead(eventId) {
|
|
4890
4935
|
if (eventId.length <= 20) return eventId;
|
|
@@ -4893,9 +4938,9 @@ function eventIdHead(eventId) {
|
|
|
4893
4938
|
function directionLabel(ev, selfDid, opts = {}) {
|
|
4894
4939
|
const senderHead = opts.fullIds ? ev.senderDid : didHead2(ev.senderDid);
|
|
4895
4940
|
const recipientHead = opts.fullIds ? ev.recipientDid : didHead2(ev.recipientDid);
|
|
4896
|
-
if (ev.senderDid === selfDid) return `${
|
|
4897
|
-
if (ev.recipientDid === selfDid) return `${
|
|
4898
|
-
return `${
|
|
4941
|
+
if (ev.senderDid === selfDid) return `${import_chalk15.default.bold("me")} \u2192 ${import_chalk15.default.dim(recipientHead)}`;
|
|
4942
|
+
if (ev.recipientDid === selfDid) return `${import_chalk15.default.dim(senderHead)} \u2192 ${import_chalk15.default.bold("me")}`;
|
|
4943
|
+
return `${import_chalk15.default.dim(senderHead)} \u2192 ${import_chalk15.default.dim(recipientHead)}`;
|
|
4899
4944
|
}
|
|
4900
4945
|
function extraDetail(ev) {
|
|
4901
4946
|
if (ev.type === "handshake_response") {
|
|
@@ -4932,7 +4977,7 @@ function parseSince(raw) {
|
|
|
4932
4977
|
}
|
|
4933
4978
|
|
|
4934
4979
|
// src/commands/guide.ts
|
|
4935
|
-
var
|
|
4980
|
+
var import_chalk16 = __toESM(require("chalk"));
|
|
4936
4981
|
|
|
4937
4982
|
// src/guide/source.ts
|
|
4938
4983
|
var GUIDE_TITLE = "HeyARP CLI \u2014 agent guide";
|
|
@@ -5161,7 +5206,7 @@ var GUIDE_SECTIONS = [
|
|
|
5161
5206
|
"Do NOT propose the receipt \u2014 the worker proposes; YOUR approval is the on-chain `escrow claim`, not any envelope.",
|
|
5162
5207
|
"Do NOT fund (`delegation fund`) before the worker has ACCEPTED \u2014 the server rejects a fund against a non-accepted delegation. Offer first, wait for accept, THEN fund.",
|
|
5163
5208
|
"Do NOT let the offer terms drift from the condition_hash \u2014 at fund time hash the SAME scope/pricing/currency you put in the offer, or the lock is rejected (ESC_LOCK_CONDITION_HASH_MISMATCH).",
|
|
5164
|
-
"
|
|
5209
|
+
"`heyarp agents` lists ONLINE agents by default (durable ~5-min liveness: a recent signed request); pass `--all` to include offline ones. That online flag is COARSER than instant reachability \u2014 `send-handshake` / `delegation offer` auto-probe the recipient and WARN if it looks idle (the envelope still lands in their inbox); add `--require-online` to abort (CLI_RECIPIENT_OFFLINE) instead. For the definitive instant state, `heyarp doctor <did>`.",
|
|
5165
5210
|
"On DELEGATION_PRICING_MISMATCH read `details` ({reason, accepted, offered}), fix that ONE term and re-offer \u2014 do NOT retry the identical offer (same result, burns a sequence each time).",
|
|
5166
5211
|
"DELEGATION_CAPACITY_EXCEEDED is the OPPOSITE: your terms are fine, the worker is just full (or closed with max-active 0). Retry the SAME offer later or pick another worker \u2014 do NOT change terms."
|
|
5167
5212
|
],
|
|
@@ -5290,7 +5335,8 @@ var GUIDE_SECTIONS = [
|
|
|
5290
5335
|
" --accepts <asset> only agents that take this asset (shorthand",
|
|
5291
5336
|
" SOL:solana-devnet or CAIP-19; accept-anything",
|
|
5292
5337
|
" agents match too) \u2014 pre-filter deal compatibility",
|
|
5293
|
-
"
|
|
5338
|
+
" (online-only by default \u2014 seen within the liveness window)",
|
|
5339
|
+
" --all include OFFLINE agents too (default hides them)",
|
|
5294
5340
|
" Sort: `--sort reputation` (default, composite desc) | `recent` |",
|
|
5295
5341
|
" `created` (oldest-first, stable `--after <id>` cursor for full",
|
|
5296
5342
|
" enumeration); reputation/recent paginate by `--page N`.",
|
|
@@ -5367,11 +5413,13 @@ var GUIDE_SECTIONS = [
|
|
|
5367
5413
|
roles: ["buyer"],
|
|
5368
5414
|
title: "Listed vs live worker + autonomous worker latency",
|
|
5369
5415
|
body: [
|
|
5370
|
-
" `heyarp agents` rows are LISTED (registered + discoverable)
|
|
5371
|
-
"
|
|
5372
|
-
" a coarse hint, NOT a guarantee the worker is
|
|
5373
|
-
"
|
|
5374
|
-
"
|
|
5416
|
+
" `heyarp agents` rows are LISTED (registered + discoverable) and, by",
|
|
5417
|
+
" default, ONLINE \u2014 but that online dot is durable-liveness (a recent",
|
|
5418
|
+
" signed request), a coarse hint, NOT a guarantee the worker is",
|
|
5419
|
+
" processing right now. `delegation offer` / `send-handshake` auto-probe",
|
|
5420
|
+
" the recipient and warn (or, with `--require-online`, abort) if idle.",
|
|
5421
|
+
" Probe the definitive state yourself with `heyarp doctor <did>`",
|
|
5422
|
+
" (LISTENING / DORMANT / UNKNOWN).",
|
|
5375
5423
|
" Autonomous LLM workers respond in 30s\u20138min typically; treat silence",
|
|
5376
5424
|
' > 15min as "try someone else". Parse inbox events as JSON:',
|
|
5377
5425
|
" heyarp inbox --json | jq '.[0].body.content.delegation_id' # paginated",
|
|
@@ -5573,7 +5621,7 @@ function renderCommand(c) {
|
|
|
5573
5621
|
${c.description}`;
|
|
5574
5622
|
}
|
|
5575
5623
|
function renderSection(s) {
|
|
5576
|
-
const lines = [
|
|
5624
|
+
const lines = [import_chalk16.default.bold(s.title)];
|
|
5577
5625
|
if (s.body && s.body.length > 0) lines.push(...s.body);
|
|
5578
5626
|
if (s.nextActions && s.nextActions.length > 0) {
|
|
5579
5627
|
lines.push(" Commands:");
|
|
@@ -5600,21 +5648,21 @@ function modeHeader(mode) {
|
|
|
5600
5648
|
""
|
|
5601
5649
|
];
|
|
5602
5650
|
case "role":
|
|
5603
|
-
return [
|
|
5651
|
+
return [import_chalk16.default.dim(`(${mode.role} guide \u2014 your slice only; run \`heyarp guide\` for the overview)`), ""];
|
|
5604
5652
|
case "setup":
|
|
5605
|
-
return [
|
|
5653
|
+
return [import_chalk16.default.dim("(setup \u2014 role-agnostic; run `heyarp guide` for the overview)"), ""];
|
|
5606
5654
|
case "troubleshoot":
|
|
5607
|
-
return [
|
|
5655
|
+
return [import_chalk16.default.dim("(troubleshooting \u2014 role-agnostic)"), ""];
|
|
5608
5656
|
}
|
|
5609
5657
|
}
|
|
5610
5658
|
function modeFooter(mode) {
|
|
5611
5659
|
if (mode.kind === "overview") {
|
|
5612
|
-
return ["",
|
|
5660
|
+
return ["", import_chalk16.default.dim("Full reference per role: `heyarp guide --role worker|buyer`. Docs: https://www.npmjs.com/package/@heyanon-arp/cli")];
|
|
5613
5661
|
}
|
|
5614
5662
|
return [];
|
|
5615
5663
|
}
|
|
5616
5664
|
function renderGuide(mode = { kind: "overview" }) {
|
|
5617
|
-
const blocks = [
|
|
5665
|
+
const blocks = [import_chalk16.default.bold(GUIDE_TITLE), "", ...modeHeader(mode)];
|
|
5618
5666
|
for (const s of selectSections(mode)) {
|
|
5619
5667
|
blocks.push(renderSection(s), "");
|
|
5620
5668
|
}
|
|
@@ -5664,7 +5712,7 @@ function renderPrompt(mode, opts = { concise: false }) {
|
|
|
5664
5712
|
// src/commands/homes.ts
|
|
5665
5713
|
var import_node_fs6 = require("fs");
|
|
5666
5714
|
var import_node_path6 = require("path");
|
|
5667
|
-
var
|
|
5715
|
+
var import_chalk17 = __toESM(require("chalk"));
|
|
5668
5716
|
var import_prompts = __toESM(require("prompts"));
|
|
5669
5717
|
|
|
5670
5718
|
// src/homes.ts
|
|
@@ -5758,27 +5806,27 @@ function runHomes(opts) {
|
|
|
5758
5806
|
return;
|
|
5759
5807
|
}
|
|
5760
5808
|
if (rows.length === 0) {
|
|
5761
|
-
console.log(
|
|
5762
|
-
console.log(
|
|
5809
|
+
console.log(import_chalk17.default.dim("(no HEYARP_HOME directories registered yet \u2014 run `heyarp register` once and the registry populates itself)"));
|
|
5810
|
+
console.log(import_chalk17.default.dim(` registry path: ${homesRegistryPath()}`));
|
|
5763
5811
|
return;
|
|
5764
5812
|
}
|
|
5765
5813
|
const header = ["Path", "Agents", "Last seen", "Status"];
|
|
5766
5814
|
const data = rows.map((r) => [
|
|
5767
|
-
r.path + (r.isCurrent ?
|
|
5815
|
+
r.path + (r.isCurrent ? import_chalk17.default.green(" (current)") : ""),
|
|
5768
5816
|
String(r.agentCount),
|
|
5769
5817
|
formatRelativeTime(r.lastSeenAt),
|
|
5770
|
-
r.exists ?
|
|
5818
|
+
r.exists ? import_chalk17.default.green("ok") : import_chalk17.default.red("missing")
|
|
5771
5819
|
]);
|
|
5772
5820
|
console.log("");
|
|
5773
5821
|
console.log(formatTable(header, data));
|
|
5774
|
-
console.log(
|
|
5822
|
+
console.log(import_chalk17.default.dim(`
|
|
5775
5823
|
Registry path: ${homesRegistryPath()}`));
|
|
5776
|
-
console.log(
|
|
5824
|
+
console.log(import_chalk17.default.dim(`Set HEYARP_HOME=<path> in a shell to switch between homes; run \`heyarp homes forget <path>\` to drop a stale entry.`));
|
|
5777
5825
|
}
|
|
5778
5826
|
async function runForget(path, opts) {
|
|
5779
5827
|
if (!opts.yes) {
|
|
5780
|
-
console.log(
|
|
5781
|
-
console.log(
|
|
5828
|
+
console.log(import_chalk17.default.yellow(`About to remove '${path}' from the homes registry.`));
|
|
5829
|
+
console.log(import_chalk17.default.dim(" Note: this only forgets the registry entry; the directory + its agents.json are NOT touched."));
|
|
5782
5830
|
const answer = await (0, import_prompts.default)(
|
|
5783
5831
|
{
|
|
5784
5832
|
type: "confirm",
|
|
@@ -5788,21 +5836,21 @@ async function runForget(path, opts) {
|
|
|
5788
5836
|
},
|
|
5789
5837
|
{
|
|
5790
5838
|
onCancel: () => {
|
|
5791
|
-
console.log(
|
|
5839
|
+
console.log(import_chalk17.default.yellow("Aborted."));
|
|
5792
5840
|
process.exit(130);
|
|
5793
5841
|
}
|
|
5794
5842
|
}
|
|
5795
5843
|
);
|
|
5796
5844
|
if (!answer.confirm) {
|
|
5797
|
-
console.log(
|
|
5845
|
+
console.log(import_chalk17.default.dim("Aborted (no changes)."));
|
|
5798
5846
|
return;
|
|
5799
5847
|
}
|
|
5800
5848
|
}
|
|
5801
5849
|
const removed = forgetHome(path);
|
|
5802
5850
|
if (removed) {
|
|
5803
|
-
console.log(
|
|
5851
|
+
console.log(import_chalk17.default.green(`\u2713 forgot ${path}`));
|
|
5804
5852
|
} else {
|
|
5805
|
-
console.log(
|
|
5853
|
+
console.log(import_chalk17.default.dim(`(no entry for ${path} in the registry \u2014 already absent)`));
|
|
5806
5854
|
}
|
|
5807
5855
|
}
|
|
5808
5856
|
function countAgents(homePath) {
|
|
@@ -5827,13 +5875,13 @@ function formatTable(header, data) {
|
|
|
5827
5875
|
const padding = " ".repeat(Math.max(0, widths[i] - lengths[i]));
|
|
5828
5876
|
return cell + padding;
|
|
5829
5877
|
}).join(" ");
|
|
5830
|
-
const headerLine =
|
|
5878
|
+
const headerLine = import_chalk17.default.bold(
|
|
5831
5879
|
pad(
|
|
5832
5880
|
header,
|
|
5833
5881
|
header.map((s) => s.length)
|
|
5834
5882
|
)
|
|
5835
5883
|
);
|
|
5836
|
-
const sepLine =
|
|
5884
|
+
const sepLine = import_chalk17.default.dim(
|
|
5837
5885
|
pad(
|
|
5838
5886
|
widths.map((w) => "-".repeat(w)),
|
|
5839
5887
|
widths
|
|
@@ -5860,7 +5908,7 @@ function formatRelativeTime(iso) {
|
|
|
5860
5908
|
}
|
|
5861
5909
|
|
|
5862
5910
|
// src/commands/inbox.ts
|
|
5863
|
-
var
|
|
5911
|
+
var import_chalk18 = __toESM(require("chalk"));
|
|
5864
5912
|
init_api();
|
|
5865
5913
|
function formatTailStartedPing(input) {
|
|
5866
5914
|
const ping = {
|
|
@@ -5907,8 +5955,8 @@ async function runInbox(positionalDid, opts) {
|
|
|
5907
5955
|
}
|
|
5908
5956
|
const api = new ArpApiClient(opts.server);
|
|
5909
5957
|
if (!opts.json) {
|
|
5910
|
-
console.log(
|
|
5911
|
-
console.log(
|
|
5958
|
+
console.log(import_chalk18.default.dim(`Server: ${api.serverUrl}`));
|
|
5959
|
+
console.log(import_chalk18.default.dim(`Signer: ${local.did}`));
|
|
5912
5960
|
}
|
|
5913
5961
|
const query = { limit };
|
|
5914
5962
|
if (opts.before) query.before = opts.before;
|
|
@@ -5922,7 +5970,7 @@ async function runInbox(positionalDid, opts) {
|
|
|
5922
5970
|
return;
|
|
5923
5971
|
}
|
|
5924
5972
|
if (events.length === 0) {
|
|
5925
|
-
console.log(
|
|
5973
|
+
console.log(import_chalk18.default.dim("\n(no events addressed to me \u2014 `heyarp events <relationship-id>` shows the chain-wide listing)"));
|
|
5926
5974
|
return;
|
|
5927
5975
|
}
|
|
5928
5976
|
console.log("");
|
|
@@ -5937,16 +5985,16 @@ async function runInbox(positionalDid, opts) {
|
|
|
5937
5985
|
secondary: `eventId=${ev.eventId} serverEventHash=${ev.serverEventHash}`
|
|
5938
5986
|
}));
|
|
5939
5987
|
}
|
|
5940
|
-
const addressedToMeHint =
|
|
5988
|
+
const addressedToMeHint = import_chalk18.default.dim(" (envelopes addressed to me \u2014 for the full chain see `heyarp events <relationship-id>`)");
|
|
5941
5989
|
if (opts.since && !opts.before) {
|
|
5942
5990
|
console.log(
|
|
5943
|
-
|
|
5991
|
+
import_chalk18.default.dim(
|
|
5944
5992
|
`
|
|
5945
5993
|
${events.length} event(s) (oldest-first).${addressedToMeHint} Advance the forward cursor with --since <serverTimestamp> --since-event-id <eventId> using the LAST row above.`
|
|
5946
5994
|
)
|
|
5947
5995
|
);
|
|
5948
5996
|
} else {
|
|
5949
|
-
console.log(
|
|
5997
|
+
console.log(import_chalk18.default.dim(`
|
|
5950
5998
|
${events.length} event(s).${addressedToMeHint} Paginate with --before <serverTimestamp> --before-event-id <eventId> using the LAST row above.`));
|
|
5951
5999
|
}
|
|
5952
6000
|
}
|
|
@@ -5961,7 +6009,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
5961
6009
|
} else {
|
|
5962
6010
|
warn(
|
|
5963
6011
|
opts.json,
|
|
5964
|
-
|
|
6012
|
+
import_chalk18.default.yellow(
|
|
5965
6013
|
"\u26A0 inbox --tail: stdout is piped but `process.stdout._handle.setBlocking` is unavailable in this Node runtime. Buffered writes may delay event delivery. Fall back to polling (`heyarp inbox --json`) if events stop arriving."
|
|
5966
6014
|
)
|
|
5967
6015
|
);
|
|
@@ -5971,9 +6019,9 @@ async function runInboxTail(did, local, opts) {
|
|
|
5971
6019
|
if (opts.json) {
|
|
5972
6020
|
console.log(formatTailStartedPing({ server: api.serverUrl, signer: local.did, stdoutBlockingApplied }));
|
|
5973
6021
|
} else {
|
|
5974
|
-
console.log(
|
|
5975
|
-
console.log(
|
|
5976
|
-
console.log(
|
|
6022
|
+
console.log(import_chalk18.default.dim(`Server: ${api.serverUrl}`));
|
|
6023
|
+
console.log(import_chalk18.default.dim(`Signer: ${local.did}`));
|
|
6024
|
+
console.log(import_chalk18.default.dim("Mode: --tail (live SSE, Ctrl-C to stop)"));
|
|
5977
6025
|
}
|
|
5978
6026
|
const controller = new AbortController();
|
|
5979
6027
|
let userAborted = false;
|
|
@@ -5992,7 +6040,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
5992
6040
|
}
|
|
5993
6041
|
if (event.type === "heartbeat") continue;
|
|
5994
6042
|
if (event.type === "connected") {
|
|
5995
|
-
console.log(
|
|
6043
|
+
console.log(import_chalk18.default.green("\u25CF stream open \u2014 listening for envelopes..."));
|
|
5996
6044
|
continue;
|
|
5997
6045
|
}
|
|
5998
6046
|
if (event.type === "envelope") {
|
|
@@ -6006,7 +6054,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
6006
6054
|
}
|
|
6007
6055
|
continue;
|
|
6008
6056
|
}
|
|
6009
|
-
console.log(
|
|
6057
|
+
console.log(import_chalk18.default.dim(`(unknown event: ${event.type})`));
|
|
6010
6058
|
}
|
|
6011
6059
|
if (!userAborted) {
|
|
6012
6060
|
throw new Error("inbox --tail: stream ended unexpectedly (server may have restarted, or change stream errored). Re-run to reconnect.");
|
|
@@ -6014,7 +6062,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
6014
6062
|
} catch (err) {
|
|
6015
6063
|
const name = err.name;
|
|
6016
6064
|
if (name === "AbortError" || userAborted) {
|
|
6017
|
-
if (!opts.json) console.log(
|
|
6065
|
+
if (!opts.json) console.log(import_chalk18.default.dim("\nstream closed."));
|
|
6018
6066
|
return;
|
|
6019
6067
|
}
|
|
6020
6068
|
throw err;
|
|
@@ -6034,15 +6082,15 @@ function formatInboxTable(events, opts = {}) {
|
|
|
6034
6082
|
]);
|
|
6035
6083
|
const widths = header.map((h, i) => Math.max(h.length, ...data.map((row) => row[i].length)));
|
|
6036
6084
|
const pad = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
6037
|
-
const lines = [
|
|
6038
|
-
const detail = events.map((ev) => ` ${
|
|
6085
|
+
const lines = [import_chalk18.default.bold(pad(header)), import_chalk18.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))];
|
|
6086
|
+
const detail = events.map((ev) => ` ${import_chalk18.default.dim("eventId:")} ${import_chalk18.default.cyan(ev.eventId)} ${import_chalk18.default.dim("serverTimestamp:")} ${import_chalk18.default.cyan(ev.serverTimestamp)}`).join("\n");
|
|
6039
6087
|
return `${lines.join("\n")}
|
|
6040
6088
|
|
|
6041
|
-
${
|
|
6089
|
+
${import_chalk18.default.bold("Pagination cursors")} (last \u2192 first):
|
|
6042
6090
|
${detail}`;
|
|
6043
6091
|
}
|
|
6044
6092
|
function hashHead2(hash) {
|
|
6045
|
-
if (!hash) return
|
|
6093
|
+
if (!hash) return import_chalk18.default.dim("(none)");
|
|
6046
6094
|
if (hash.length <= 14) return hash;
|
|
6047
6095
|
return `${hash.slice(0, 14)}...`;
|
|
6048
6096
|
}
|
|
@@ -6059,7 +6107,7 @@ function parseLimit4(raw) {
|
|
|
6059
6107
|
var import_node_crypto2 = require("crypto");
|
|
6060
6108
|
var import_node_fs7 = require("fs");
|
|
6061
6109
|
var import_sdk19 = require("@heyanon-arp/sdk");
|
|
6062
|
-
var
|
|
6110
|
+
var import_chalk19 = __toESM(require("chalk"));
|
|
6063
6111
|
function writeSecretFile(path, body) {
|
|
6064
6112
|
const tmp = `${path}.tmp.${(0, import_node_crypto2.randomBytes)(8).toString("hex")}`;
|
|
6065
6113
|
const fd = (0, import_node_fs7.openSync)(tmp, "wx", 384);
|
|
@@ -6089,16 +6137,16 @@ function registerKeysCommand(root) {
|
|
|
6089
6137
|
const identity = (0, import_sdk19.generateKeyPair)();
|
|
6090
6138
|
const settlement = (0, import_sdk19.generateKeyPair)();
|
|
6091
6139
|
const out = [
|
|
6092
|
-
|
|
6093
|
-
` public (base58btc): ${
|
|
6094
|
-
` secret (base64) : ${
|
|
6140
|
+
import_chalk19.default.bold("Identity key (Ed25519)"),
|
|
6141
|
+
` public (base58btc): ${import_chalk19.default.cyan((0, import_sdk19.base58btcEncode)(identity.publicKey))}`,
|
|
6142
|
+
` secret (base64) : ${import_chalk19.default.yellow(Buffer.from(identity.secretKey).toString("base64"))}`,
|
|
6095
6143
|
"",
|
|
6096
|
-
|
|
6097
|
-
` public (base58btc): ${
|
|
6098
|
-
` secret (base64) : ${
|
|
6144
|
+
import_chalk19.default.bold("Settlement key (Ed25519)"),
|
|
6145
|
+
` public (base58btc): ${import_chalk19.default.cyan((0, import_sdk19.base58btcEncode)(settlement.publicKey))}`,
|
|
6146
|
+
` secret (base64) : ${import_chalk19.default.yellow(Buffer.from(settlement.secretKey).toString("base64"))}`,
|
|
6099
6147
|
"",
|
|
6100
|
-
|
|
6101
|
-
` ${
|
|
6148
|
+
import_chalk19.default.bold("Resulting DID"),
|
|
6149
|
+
` ${import_chalk19.default.cyan((0, import_sdk19.formatDid)(identity.publicKey))}`
|
|
6102
6150
|
];
|
|
6103
6151
|
console.log(out.join("\n"));
|
|
6104
6152
|
});
|
|
@@ -6107,11 +6155,11 @@ function registerKeysCommand(root) {
|
|
|
6107
6155
|
const json = JSON.stringify(toKeyBundle(agent, (/* @__PURE__ */ new Date()).toISOString()), null, 2);
|
|
6108
6156
|
if (opts.out) {
|
|
6109
6157
|
writeSecretFile(opts.out, json);
|
|
6110
|
-
process.stderr.write(
|
|
6158
|
+
process.stderr.write(import_chalk19.default.yellow(`\u26A0 wrote SECRET key bundle to ${opts.out} (mode 0600) \u2014 keep it offline; anyone with this file can operate ${did}.
|
|
6111
6159
|
`));
|
|
6112
6160
|
console.log(opts.out);
|
|
6113
6161
|
} else {
|
|
6114
|
-
process.stderr.write(
|
|
6162
|
+
process.stderr.write(import_chalk19.default.yellow("\u26A0 this is a SECRET key bundle \u2014 redirect to a file and keep it offline.\n"));
|
|
6115
6163
|
console.log(json);
|
|
6116
6164
|
}
|
|
6117
6165
|
});
|
|
@@ -6119,8 +6167,8 @@ function registerKeysCommand(root) {
|
|
|
6119
6167
|
const seed = decodeSeed(secretKeyB64);
|
|
6120
6168
|
const pub = (0, import_sdk19.getPublicKey)(seed);
|
|
6121
6169
|
const did = (0, import_sdk19.formatDid)(pub);
|
|
6122
|
-
console.log(`${
|
|
6123
|
-
console.log(`${
|
|
6170
|
+
console.log(`${import_chalk19.default.bold("DID")}: ${import_chalk19.default.cyan(did)}`);
|
|
6171
|
+
console.log(`${import_chalk19.default.bold("Identity public key (base58btc)")}: ${import_chalk19.default.cyan((0, import_sdk19.base58btcEncode)(pub))}`);
|
|
6124
6172
|
});
|
|
6125
6173
|
}
|
|
6126
6174
|
function decodeSeed(b64) {
|
|
@@ -6137,7 +6185,7 @@ function decodeSeed(b64) {
|
|
|
6137
6185
|
}
|
|
6138
6186
|
|
|
6139
6187
|
// src/commands/list.ts
|
|
6140
|
-
var
|
|
6188
|
+
var import_chalk20 = __toESM(require("chalk"));
|
|
6141
6189
|
function registerListCommand(root) {
|
|
6142
6190
|
root.command("list").description("List agents registered locally (~/.heyarp/agents.json)").option("--json", "Machine-readable mode \u2014 emit the local agents as a single JSON array on stdout ({serverUrl, did, name, tags, registeredAt}[]).", false).action((opts) => {
|
|
6143
6191
|
const rows = listAgents();
|
|
@@ -6146,7 +6194,7 @@ function registerListCommand(root) {
|
|
|
6146
6194
|
return;
|
|
6147
6195
|
}
|
|
6148
6196
|
if (rows.length === 0) {
|
|
6149
|
-
console.log(
|
|
6197
|
+
console.log(import_chalk20.default.dim(`No local agents. State file: ${stateFilePath()}`));
|
|
6150
6198
|
return;
|
|
6151
6199
|
}
|
|
6152
6200
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -6158,7 +6206,7 @@ function registerListCommand(root) {
|
|
|
6158
6206
|
for (const [serverUrl, group] of grouped) {
|
|
6159
6207
|
if (!first) console.log("");
|
|
6160
6208
|
first = false;
|
|
6161
|
-
console.log(
|
|
6209
|
+
console.log(import_chalk20.default.bold(`Server: ${serverUrl}`));
|
|
6162
6210
|
console.log(formatAgentsTable(group.map(({ agent }) => ({ did: agent.did, name: agent.name, tags: agent.tags, registeredAt: agent.registeredAt }))));
|
|
6163
6211
|
}
|
|
6164
6212
|
});
|
|
@@ -6166,7 +6214,7 @@ function registerListCommand(root) {
|
|
|
6166
6214
|
|
|
6167
6215
|
// src/commands/login.ts
|
|
6168
6216
|
var import_node_crypto3 = require("crypto");
|
|
6169
|
-
var
|
|
6217
|
+
var import_chalk21 = __toESM(require("chalk"));
|
|
6170
6218
|
init_api();
|
|
6171
6219
|
var POLL_INTERVAL_MS = 2e3;
|
|
6172
6220
|
var POLL_TIMEOUT_MS = 11 * 6e4;
|
|
@@ -6236,9 +6284,9 @@ function registerLoginCommand(root) {
|
|
|
6236
6284
|
jsonOut({ serverUrl: result.serverUrl, wallet: result.wallet, credentialsPath: credentialsFilePath() });
|
|
6237
6285
|
} else {
|
|
6238
6286
|
console.log("");
|
|
6239
|
-
console.log(`${
|
|
6240
|
-
console.log(
|
|
6241
|
-
console.log(
|
|
6287
|
+
console.log(`${import_chalk21.default.green("Logged in as")} ${import_chalk21.default.cyan(result.wallet)}`);
|
|
6288
|
+
console.log(import_chalk21.default.dim(`If that is not the wallet you approved with, run heyarp logout immediately.`));
|
|
6289
|
+
console.log(import_chalk21.default.dim(`Credential saved to ${credentialsFilePath()} (mode 0600).`));
|
|
6242
6290
|
}
|
|
6243
6291
|
} catch (err) {
|
|
6244
6292
|
emitActionError(err, cmd);
|
|
@@ -6248,7 +6296,7 @@ function registerLoginCommand(root) {
|
|
|
6248
6296
|
}
|
|
6249
6297
|
|
|
6250
6298
|
// src/commands/logout.ts
|
|
6251
|
-
var
|
|
6299
|
+
var import_chalk22 = __toESM(require("chalk"));
|
|
6252
6300
|
init_api();
|
|
6253
6301
|
function registerLogoutCommand(root) {
|
|
6254
6302
|
root.command("logout").description("Log out of the ARP server: revoke the stored CLI auth token (best-effort) and delete the local credential for this server.").option("--server <url>", "Override ARP server base URL").option("--json", "machine-readable output ({ serverUrl, loggedOut, wallet? })", false).action(async (opts, cmd) => {
|
|
@@ -6273,7 +6321,7 @@ function registerLogoutCommand(root) {
|
|
|
6273
6321
|
if (opts.json) {
|
|
6274
6322
|
jsonOut({ serverUrl: api.serverUrl, loggedOut: true, wallet: credential.wallet });
|
|
6275
6323
|
} else {
|
|
6276
|
-
console.log(`${
|
|
6324
|
+
console.log(`${import_chalk22.default.green("Logged out of")} ${api.serverUrl} ${import_chalk22.default.dim(`(was ${credential.wallet})`)}`);
|
|
6277
6325
|
}
|
|
6278
6326
|
} catch (err) {
|
|
6279
6327
|
emitActionError(err, cmd);
|
|
@@ -6284,7 +6332,7 @@ function registerLogoutCommand(root) {
|
|
|
6284
6332
|
|
|
6285
6333
|
// src/commands/name.ts
|
|
6286
6334
|
var import_sdk20 = require("@heyanon-arp/sdk");
|
|
6287
|
-
var
|
|
6335
|
+
var import_chalk23 = __toESM(require("chalk"));
|
|
6288
6336
|
init_api();
|
|
6289
6337
|
function registerNameCommand(root) {
|
|
6290
6338
|
const name = root.command("name").description("Agent name (handle) utilities.");
|
|
@@ -6307,7 +6355,7 @@ async function runNameCheck(input, opts) {
|
|
|
6307
6355
|
return { name, available: false, reason: "reserved" };
|
|
6308
6356
|
}
|
|
6309
6357
|
const api = new ArpApiClient(opts.server);
|
|
6310
|
-
progress(opts.json,
|
|
6358
|
+
progress(opts.json, import_chalk23.default.dim(`Server: ${api.serverUrl}`));
|
|
6311
6359
|
try {
|
|
6312
6360
|
const profile = await api.discoverByName(name);
|
|
6313
6361
|
return { name, available: false, reason: "taken", did: profile.did };
|
|
@@ -6321,22 +6369,22 @@ async function runNameCheck(input, opts) {
|
|
|
6321
6369
|
function printNameCheck(input, r) {
|
|
6322
6370
|
switch (r.reason) {
|
|
6323
6371
|
case "invalid":
|
|
6324
|
-
console.log(`${
|
|
6372
|
+
console.log(`${import_chalk23.default.red("\u2717")} '${input}' is not a valid handle \u2014 must be lowercase a-z0-9_, 3-32 chars.`);
|
|
6325
6373
|
break;
|
|
6326
6374
|
case "reserved":
|
|
6327
|
-
console.log(`${
|
|
6375
|
+
console.log(`${import_chalk23.default.red("\u2717")} '${r.name}' is reserved and cannot be registered.`);
|
|
6328
6376
|
break;
|
|
6329
6377
|
case "taken":
|
|
6330
|
-
console.log(`${
|
|
6378
|
+
console.log(`${import_chalk23.default.yellow("\u2717")} '${r.name}' is taken \u2192 ${import_chalk23.default.cyan(r.did ?? "(unknown DID)")}`);
|
|
6331
6379
|
break;
|
|
6332
6380
|
default:
|
|
6333
|
-
console.log(`${
|
|
6381
|
+
console.log(`${import_chalk23.default.green("\u2713")} '${r.name}' is available.`);
|
|
6334
6382
|
}
|
|
6335
6383
|
}
|
|
6336
6384
|
|
|
6337
6385
|
// src/commands/profile.ts
|
|
6338
6386
|
var import_sdk21 = require("@heyanon-arp/sdk");
|
|
6339
|
-
var
|
|
6387
|
+
var import_chalk24 = __toESM(require("chalk"));
|
|
6340
6388
|
init_api();
|
|
6341
6389
|
function registerProfileCommand(root) {
|
|
6342
6390
|
root.command("profile").description("Composed agent profile: public fields + reputation + liveness, in one read.").argument("<did>", "did:arp:<base58btc> identifier").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the profile as JSON on stdout.", false).action(async (did, opts) => {
|
|
@@ -6351,26 +6399,26 @@ function registerProfileCommand(root) {
|
|
|
6351
6399
|
}
|
|
6352
6400
|
const j = false;
|
|
6353
6401
|
const s = p.reputation.scores;
|
|
6354
|
-
const live = p.liveness.online ?
|
|
6402
|
+
const live = p.liveness.online ? import_chalk24.default.green("\u25CF online") : import_chalk24.default.dim("\u25CB offline");
|
|
6355
6403
|
const tags = p.tags.map(sanitizeForTerminal).filter((t) => t.length > 0);
|
|
6356
|
-
progress(j,
|
|
6357
|
-
if (p.description) progress(j,
|
|
6358
|
-
progress(j, ` ${live}${p.liveness.inboxStreamActive ?
|
|
6359
|
-
progress(j, ` tags: ${tags.length ? tags.join(", ") :
|
|
6404
|
+
progress(j, import_chalk24.default.bold(`${p.name ? sanitizeForTerminal(p.name) : "(unnamed)"} ${import_chalk24.default.dim(p.did)}`));
|
|
6405
|
+
if (p.description) progress(j, import_chalk24.default.dim(` ${sanitizeForTerminal(p.description)}`));
|
|
6406
|
+
progress(j, ` ${live}${p.liveness.inboxStreamActive ? import_chalk24.default.green(" \xB7 stream attached") : ""} \xB7 last seen ${p.liveness.lastSeenAt ?? "\u2014"}`);
|
|
6407
|
+
progress(j, ` tags: ${tags.length ? tags.join(", ") : import_chalk24.default.dim("none")}`);
|
|
6360
6408
|
progress(j, "");
|
|
6361
|
-
progress(j,
|
|
6409
|
+
progress(j, import_chalk24.default.bold(" Reputation") + import_chalk24.default.dim(" (informational)"));
|
|
6362
6410
|
progress(
|
|
6363
6411
|
j,
|
|
6364
6412
|
` composite ${s.composite.toFixed(2)} \xB7 reliability ${s.reliability.toFixed(2)} \xB7 settlement ${s.settlement.toFixed(2)} \xB7 dispute-health ${s.disputeHealth.toFixed(2)}`
|
|
6365
6413
|
);
|
|
6366
|
-
progress(j,
|
|
6414
|
+
progress(j, import_chalk24.default.dim(` ${p.reputation.computed ? `computed ${p.reputation.lastComputedAt}` : "never computed (neutral cold-start)"}`));
|
|
6367
6415
|
});
|
|
6368
6416
|
}
|
|
6369
6417
|
|
|
6370
6418
|
// src/commands/receipt.ts
|
|
6371
6419
|
var import_sdk22 = require("@heyanon-arp/sdk");
|
|
6372
6420
|
var import_shield2 = require("@heyanon-arp/shield");
|
|
6373
|
-
var
|
|
6421
|
+
var import_chalk25 = __toESM(require("chalk"));
|
|
6374
6422
|
init_api();
|
|
6375
6423
|
function registerReceiptCommands(root) {
|
|
6376
6424
|
const cmd = root.command("receipt").description("Receipt envelopes \u2014 the payee proposes a delivery record (payment consent is on-chain via claim_work_payment)");
|
|
@@ -6397,7 +6445,7 @@ function registerPropose(parent) {
|
|
|
6397
6445
|
} catch (err) {
|
|
6398
6446
|
emitActionError(err, cmd);
|
|
6399
6447
|
if (!opts.json && err instanceof ApiError && err.payload.code === "RECEIPT_ALREADY_EXISTS") {
|
|
6400
|
-
console.error(
|
|
6448
|
+
console.error(import_chalk25.default.dim(" This receipt already exists (a prior propose committed it). Do NOT re-propose \u2014 payment consent is on-chain (claim_work_payment)."));
|
|
6401
6449
|
}
|
|
6402
6450
|
process.exitCode = 1;
|
|
6403
6451
|
}
|
|
@@ -6423,7 +6471,7 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6423
6471
|
opts.relId = await resolveAutoRelId(api, sender, delegationId);
|
|
6424
6472
|
progress(
|
|
6425
6473
|
opts.json,
|
|
6426
|
-
|
|
6474
|
+
import_chalk25.default.dim(`[auto-rel-id] resolved --rel-id=${opts.relId} (delegation found in exactly one of your relationships; pass --rel-id explicitly to override)`)
|
|
6427
6475
|
);
|
|
6428
6476
|
}
|
|
6429
6477
|
if (opts.relId) {
|
|
@@ -6439,7 +6487,7 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6439
6487
|
opts.requestId = await resolveAutoRequestId(api, sender, opts.relId, delegationId);
|
|
6440
6488
|
progress(
|
|
6441
6489
|
opts.json,
|
|
6442
|
-
|
|
6490
|
+
import_chalk25.default.dim(
|
|
6443
6491
|
`[auto-request-id] resolved --request-id=${opts.requestId} (unique 'responded' work_log under this delegation; pass --request-id explicitly to override)`
|
|
6444
6492
|
)
|
|
6445
6493
|
);
|
|
@@ -6458,8 +6506,8 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6458
6506
|
}
|
|
6459
6507
|
requestHash = computed.requestHash;
|
|
6460
6508
|
responseHash = computed.responseHash;
|
|
6461
|
-
progress(opts.json,
|
|
6462
|
-
progress(opts.json,
|
|
6509
|
+
progress(opts.json, import_chalk25.default.dim(`[auto-hashes] request_hash: ${requestHash} (from work-log ${opts.relId}/${delegationId}/${opts.requestId})`));
|
|
6510
|
+
progress(opts.json, import_chalk25.default.dim(`[auto-hashes] response_hash: ${responseHash}`));
|
|
6463
6511
|
} else {
|
|
6464
6512
|
if (requestHashArg === void 0 || responseHashArg === void 0) {
|
|
6465
6513
|
throw new Error("receipt propose: <request-hash> and <response-hash> are required (or pass --auto-hashes + --rel-id + --request-id to derive them from the work-log)");
|
|
@@ -6479,11 +6527,11 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6479
6527
|
if (opts.deliverableHash) content.deliverable_hash = opts.deliverableHash;
|
|
6480
6528
|
if (usage) content.usage = usage;
|
|
6481
6529
|
const body = { type: "receipt", content };
|
|
6482
|
-
progress(opts.json,
|
|
6483
|
-
progress(opts.json,
|
|
6484
|
-
progress(opts.json,
|
|
6485
|
-
progress(opts.json,
|
|
6486
|
-
progress(opts.json,
|
|
6530
|
+
progress(opts.json, import_chalk25.default.dim(`Server: ${api.serverUrl}`));
|
|
6531
|
+
progress(opts.json, import_chalk25.default.dim(`Sender (payee): ${sender.did}`));
|
|
6532
|
+
progress(opts.json, import_chalk25.default.dim(`Recipient (caller): ${recipientDid}`));
|
|
6533
|
+
progress(opts.json, import_chalk25.default.dim(`Delegation: ${delegationId}`));
|
|
6534
|
+
progress(opts.json, import_chalk25.default.dim(`Verdict (proposed): ${verdict}`));
|
|
6487
6535
|
const result = await sendReceiptEnvelope({ api, sender, recipientDid, body, attachments: void 0, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
6488
6536
|
if (opts.json) {
|
|
6489
6537
|
const json = {
|
|
@@ -6504,10 +6552,10 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6504
6552
|
return;
|
|
6505
6553
|
}
|
|
6506
6554
|
printIngestResult2(result);
|
|
6507
|
-
console.log(
|
|
6508
|
-
Receipt event hash: ${
|
|
6509
|
-
console.log(
|
|
6510
|
-
console.log(
|
|
6555
|
+
console.log(import_chalk25.default.dim(`
|
|
6556
|
+
Receipt event hash: ${import_chalk25.default.cyan(result.serverEventHash)}`));
|
|
6557
|
+
console.log(import_chalk25.default.dim("Receipt recorded. Payment consent is ON-CHAIN now: the buyer approves by"));
|
|
6558
|
+
console.log(import_chalk25.default.dim("sending claim_work_payment (or you self-claim after the review window)."));
|
|
6511
6559
|
}
|
|
6512
6560
|
async function assertSenderIsReceiptPayee(api, sender, relationshipId, delegationId) {
|
|
6513
6561
|
const signer = makeSigner(sender);
|
|
@@ -6618,7 +6666,7 @@ async function sendReceiptEnvelope(args) {
|
|
|
6618
6666
|
attachments: args.attachments
|
|
6619
6667
|
});
|
|
6620
6668
|
if (args.verbose) {
|
|
6621
|
-
console.log(
|
|
6669
|
+
console.log(import_chalk25.default.bold("\nEnvelope (pre-send):"));
|
|
6622
6670
|
console.log(formatJson(envelope));
|
|
6623
6671
|
}
|
|
6624
6672
|
try {
|
|
@@ -6633,12 +6681,12 @@ async function sendReceiptEnvelope(args) {
|
|
|
6633
6681
|
}
|
|
6634
6682
|
}
|
|
6635
6683
|
function printIngestResult2(result) {
|
|
6636
|
-
console.log(
|
|
6637
|
-
console.log(`${
|
|
6638
|
-
console.log(`${
|
|
6639
|
-
console.log(`${
|
|
6640
|
-
console.log(`${
|
|
6641
|
-
console.log(`${
|
|
6684
|
+
console.log(import_chalk25.default.green("\nDelivered."));
|
|
6685
|
+
console.log(`${import_chalk25.default.bold("Event id")}: ${import_chalk25.default.cyan(result.eventId)}`);
|
|
6686
|
+
console.log(`${import_chalk25.default.bold("Relationship id")}: ${import_chalk25.default.cyan(result.relationshipId)}`);
|
|
6687
|
+
console.log(`${import_chalk25.default.bold("Chain index")}: ${import_chalk25.default.cyan(String(result.relationshipEventIndex))}`);
|
|
6688
|
+
console.log(`${import_chalk25.default.bold("Server timestamp")}: ${import_chalk25.default.cyan(result.serverTimestamp)}`);
|
|
6689
|
+
console.log(`${import_chalk25.default.bold("Server event hash")}: ${import_chalk25.default.cyan(result.serverEventHash)}`);
|
|
6642
6690
|
}
|
|
6643
6691
|
function parseVerdict(cmdName, raw) {
|
|
6644
6692
|
if (raw === void 0 || raw === "") return import_sdk22.ReceiptVerdicts.ACCEPTED;
|
|
@@ -6683,7 +6731,7 @@ function requireSha256(cmdName, raw, label) {
|
|
|
6683
6731
|
|
|
6684
6732
|
// src/commands/receipts.ts
|
|
6685
6733
|
var import_sdk23 = require("@heyanon-arp/sdk");
|
|
6686
|
-
var
|
|
6734
|
+
var import_chalk26 = __toESM(require("chalk"));
|
|
6687
6735
|
init_api();
|
|
6688
6736
|
function registerReceiptsCommand(root) {
|
|
6689
6737
|
root.command("receipts").description(
|
|
@@ -6706,9 +6754,9 @@ async function runReceipts(relationshipId, opts) {
|
|
|
6706
6754
|
const api = new ArpApiClient(opts.server);
|
|
6707
6755
|
const sender = resolveSenderAgent("receipts", opts.server, opts.fromDid, opts.from);
|
|
6708
6756
|
if (!opts.json) {
|
|
6709
|
-
console.log(
|
|
6710
|
-
console.log(
|
|
6711
|
-
console.log(
|
|
6757
|
+
console.log(import_chalk26.default.dim(`Server: ${api.serverUrl}`));
|
|
6758
|
+
console.log(import_chalk26.default.dim(`Signer: ${sender.did}`));
|
|
6759
|
+
console.log(import_chalk26.default.dim(`Relationship: ${relationshipId}`));
|
|
6712
6760
|
}
|
|
6713
6761
|
const query = { limit };
|
|
6714
6762
|
if (opts.delegationId) query.delegationId = opts.delegationId;
|
|
@@ -6720,7 +6768,7 @@ async function runReceipts(relationshipId, opts) {
|
|
|
6720
6768
|
return;
|
|
6721
6769
|
}
|
|
6722
6770
|
if (rows.length === 0) {
|
|
6723
|
-
console.log(
|
|
6771
|
+
console.log(import_chalk26.default.dim("\n(no receipts for this relationship)"));
|
|
6724
6772
|
return;
|
|
6725
6773
|
}
|
|
6726
6774
|
console.log("");
|
|
@@ -6737,29 +6785,29 @@ async function runReceipts(relationshipId, opts) {
|
|
|
6737
6785
|
}));
|
|
6738
6786
|
}
|
|
6739
6787
|
const lastId = rows[rows.length - 1].id;
|
|
6740
|
-
console.log(
|
|
6788
|
+
console.log(import_chalk26.default.dim(`
|
|
6741
6789
|
${rows.length} receipt row(s). Paginate with --after ${lastId}.`));
|
|
6742
6790
|
}
|
|
6743
6791
|
function formatReceiptLine(r, selfDid, opts = {}) {
|
|
6744
6792
|
const delegationPart = opts.fullIds ? r.delegationId : idHead2(r.delegationId);
|
|
6745
6793
|
const requestHashPart = opts.fullIds ? r.requestHash : hashHead3(r.requestHash);
|
|
6746
|
-
const id =
|
|
6794
|
+
const id = import_chalk26.default.bold(`${delegationPart}/${requestHashPart}`);
|
|
6747
6795
|
const callerHead = opts.fullIds ? r.callerDid : didHead3(r.callerDid);
|
|
6748
6796
|
const payeeHead = opts.fullIds ? r.payeeDid : didHead3(r.payeeDid);
|
|
6749
|
-
const direction = r.payeeDid === selfDid ? `${
|
|
6797
|
+
const direction = r.payeeDid === selfDid ? `${import_chalk26.default.bold("me")}(payee) \u2192 ${import_chalk26.default.dim(callerHead)}` : `${import_chalk26.default.dim(payeeHead)}(payee) \u2192 ${import_chalk26.default.bold("me")}`;
|
|
6750
6798
|
const verdict = formatVerdict(r);
|
|
6751
6799
|
const responseTail = opts.fullIds ? `
|
|
6752
|
-
${
|
|
6800
|
+
${import_chalk26.default.dim("responseHash:")} ${import_chalk26.default.cyan(r.responseHash)}` : "";
|
|
6753
6801
|
return `${id} ${direction} ${verdict}${responseTail}`;
|
|
6754
6802
|
}
|
|
6755
6803
|
function formatVerdict(r) {
|
|
6756
6804
|
switch (r.verdictProposed) {
|
|
6757
6805
|
case import_sdk23.ReceiptVerdicts.ACCEPTED:
|
|
6758
|
-
return
|
|
6806
|
+
return import_chalk26.default.green("accepted");
|
|
6759
6807
|
case import_sdk23.ReceiptVerdicts.ACCEPTED_WITH_NOTES:
|
|
6760
|
-
return
|
|
6808
|
+
return import_chalk26.default.yellow("accepted_with_notes");
|
|
6761
6809
|
case import_sdk23.ReceiptVerdicts.REJECTED:
|
|
6762
|
-
return
|
|
6810
|
+
return import_chalk26.default.red("rejected");
|
|
6763
6811
|
}
|
|
6764
6812
|
}
|
|
6765
6813
|
function idHead2(id) {
|
|
@@ -6786,7 +6834,7 @@ function parseLimit5(raw) {
|
|
|
6786
6834
|
// src/commands/recover.ts
|
|
6787
6835
|
var import_node_fs8 = require("fs");
|
|
6788
6836
|
var import_sdk24 = require("@heyanon-arp/sdk");
|
|
6789
|
-
var
|
|
6837
|
+
var import_chalk27 = __toESM(require("chalk"));
|
|
6790
6838
|
init_api();
|
|
6791
6839
|
function registerRecoverCommand(root) {
|
|
6792
6840
|
root.command("recover").description(
|
|
@@ -6822,7 +6870,7 @@ async function runRecover(opts) {
|
|
|
6822
6870
|
}
|
|
6823
6871
|
if (bundle.ownerWallet && bundle.ownerWallet !== credential.wallet) {
|
|
6824
6872
|
process.stderr.write(
|
|
6825
|
-
|
|
6873
|
+
import_chalk27.default.yellow(
|
|
6826
6874
|
`\u26A0 this bundle was exported under wallet ${bundle.ownerWallet}, but you are logged in as ${credential.wallet}. The server will reject the recover unless the agent is yours.
|
|
6827
6875
|
`
|
|
6828
6876
|
)
|
|
@@ -6839,7 +6887,7 @@ async function runRecover(opts) {
|
|
|
6839
6887
|
lastSenderSequence = seq.lastSenderSequence;
|
|
6840
6888
|
} catch (err) {
|
|
6841
6889
|
process.stderr.write(
|
|
6842
|
-
|
|
6890
|
+
import_chalk27.default.yellow(
|
|
6843
6891
|
`\u26A0 could not read the sender sequence from the server (${err.message}). If sends are rejected as backwards, run \`heyarp escrow recover-sequence --apply\`.
|
|
6844
6892
|
`
|
|
6845
6893
|
)
|
|
@@ -6867,14 +6915,14 @@ async function runRecover(opts) {
|
|
|
6867
6915
|
jsonOut({ recovered: true, did: derivedDid, name: row.name });
|
|
6868
6916
|
return;
|
|
6869
6917
|
}
|
|
6870
|
-
console.log(
|
|
6918
|
+
console.log(import_chalk27.default.green(`\u2713 Recovered ${row.name ? `${row.name} ` : ""}${derivedDid} into local state \u2014 you can operate it now.`));
|
|
6871
6919
|
}
|
|
6872
6920
|
|
|
6873
6921
|
// src/commands/register.ts
|
|
6874
6922
|
var import_node_crypto4 = require("crypto");
|
|
6875
6923
|
var import_node_fs9 = require("fs");
|
|
6876
6924
|
var import_sdk25 = require("@heyanon-arp/sdk");
|
|
6877
|
-
var
|
|
6925
|
+
var import_chalk28 = __toESM(require("chalk"));
|
|
6878
6926
|
var import_prompts2 = __toESM(require("prompts"));
|
|
6879
6927
|
init_api();
|
|
6880
6928
|
init_paths();
|
|
@@ -6928,7 +6976,7 @@ var defaultRegisterDeps = {
|
|
|
6928
6976
|
async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
6929
6977
|
assertJsonRequiresYes(opts);
|
|
6930
6978
|
const api = deps.makeApi(opts.server);
|
|
6931
|
-
if (!opts.json) console.log(
|
|
6979
|
+
if (!opts.json) console.log(import_chalk28.default.dim(`Server: ${api.serverUrl}`));
|
|
6932
6980
|
const credential = requireCredential("register", api.serverUrl);
|
|
6933
6981
|
if (!opts.json) {
|
|
6934
6982
|
warnIfAgentsAlreadyRegistered(opts.server);
|
|
@@ -6936,10 +6984,10 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
6936
6984
|
}
|
|
6937
6985
|
const keys = opts.fromKeys ? loadKeysFromFile(opts.fromKeys) : freshKeys();
|
|
6938
6986
|
const did = (0, import_sdk25.formatDid)(keys.identityPublicKey);
|
|
6939
|
-
if (!opts.json) console.log(
|
|
6987
|
+
if (!opts.json) console.log(import_chalk28.default.dim(`DID will be: ${did}`));
|
|
6940
6988
|
const answers = await mergeAnswers(opts);
|
|
6941
6989
|
const scryptSalt = (0, import_node_crypto4.randomBytes)(16);
|
|
6942
|
-
if (!opts.json) console.log(
|
|
6990
|
+
if (!opts.json) console.log(import_chalk28.default.dim("Deriving scrypt key, this may take a moment..."));
|
|
6943
6991
|
const scryptKey = (0, import_sdk25.deriveScryptKey)(answers.password, new Uint8Array(scryptSalt));
|
|
6944
6992
|
const challenge = await api.issueChallenge("register");
|
|
6945
6993
|
const challengeBytes = base64UrlNoPadDecode(challenge.challengeB64);
|
|
@@ -7027,19 +7075,19 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
7027
7075
|
try {
|
|
7028
7076
|
recordHome(arpHomeDir());
|
|
7029
7077
|
} catch (registryErr) {
|
|
7030
|
-
if (!opts.json) console.log(
|
|
7078
|
+
if (!opts.json) console.log(import_chalk28.default.dim(`(homes registry write failed: ${registryErr.message})`));
|
|
7031
7079
|
}
|
|
7032
7080
|
if (!opts.json) {
|
|
7033
|
-
console.log(
|
|
7034
|
-
console.log(`${
|
|
7035
|
-
console.log(`${
|
|
7036
|
-
console.log(`${
|
|
7037
|
-
console.log(
|
|
7081
|
+
console.log(import_chalk28.default.green("\nRegistered."));
|
|
7082
|
+
console.log(`${import_chalk28.default.bold("DID")}: ${import_chalk28.default.cyan(result.did)}`);
|
|
7083
|
+
console.log(`${import_chalk28.default.bold("Settlement pubkey")} ${import_chalk28.default.dim("(fund with SOL)")}: ${import_chalk28.default.cyan(settlementPublicKeyB58)}`);
|
|
7084
|
+
console.log(`${import_chalk28.default.bold("Owner account")}: ${import_chalk28.default.cyan(credential.wallet)}`);
|
|
7085
|
+
console.log(import_chalk28.default.bold("DID document:"));
|
|
7038
7086
|
console.log(formatJson(result.didDocument));
|
|
7039
7087
|
}
|
|
7040
|
-
if (!opts.json) console.log(
|
|
7088
|
+
if (!opts.json) console.log(import_chalk28.default.green(`
|
|
7041
7089
|
\u2713 Discoverable now via \`heyarp agents\`.`));
|
|
7042
|
-
if (!opts.json) console.log(
|
|
7090
|
+
if (!opts.json) console.log(import_chalk28.default.dim(`
|
|
7043
7091
|
Local state saved to ${arpHomeDir()}/agents.json (mode 0600).`));
|
|
7044
7092
|
if (opts.json) {
|
|
7045
7093
|
console.log(
|
|
@@ -7112,7 +7160,7 @@ async function mergeAnswers(opts) {
|
|
|
7112
7160
|
}
|
|
7113
7161
|
const prompted = promptDefs.length > 0 ? await (0, import_prompts2.default)(promptDefs, {
|
|
7114
7162
|
onCancel: () => {
|
|
7115
|
-
console.log(
|
|
7163
|
+
console.log(import_chalk28.default.yellow("\nAborted."));
|
|
7116
7164
|
process.exit(130);
|
|
7117
7165
|
}
|
|
7118
7166
|
}) : {};
|
|
@@ -7144,16 +7192,16 @@ function warnIfOrphanHomesPresent() {
|
|
|
7144
7192
|
try {
|
|
7145
7193
|
others = listHomes().filter((h) => h.path !== current);
|
|
7146
7194
|
} catch (registryErr) {
|
|
7147
|
-
console.log(
|
|
7195
|
+
console.log(import_chalk28.default.dim(`(homes registry unreadable, skipping orphan-home check: ${registryErr.message})`));
|
|
7148
7196
|
return;
|
|
7149
7197
|
}
|
|
7150
7198
|
if (others.length === 0) return;
|
|
7151
|
-
const list = others.map((h) => ` \u2022 ${
|
|
7152
|
-
console.log(
|
|
7199
|
+
const list = others.map((h) => ` \u2022 ${import_chalk28.default.cyan(h.path)} ${import_chalk28.default.dim(`(last seen ${h.lastSeenAt})`)}`).join("\n");
|
|
7200
|
+
console.log(import_chalk28.default.yellow(`
|
|
7153
7201
|
\u26A0 HEYARP_HOME is unset, but other agent homes are registered on this machine:`));
|
|
7154
7202
|
console.log(list);
|
|
7155
7203
|
console.log(
|
|
7156
|
-
|
|
7204
|
+
import_chalk28.default.dim(
|
|
7157
7205
|
` Registering will create a NEW agent under ${current}.
|
|
7158
7206
|
If you meant to add to an existing home, abort (Ctrl-C) and re-run with:
|
|
7159
7207
|
HEYARP_HOME=<path> heyarp register \u2026
|
|
@@ -7166,11 +7214,11 @@ function warnIfAgentsAlreadyRegistered(serverOverride) {
|
|
|
7166
7214
|
const targetServer = resolveServerUrl(serverOverride);
|
|
7167
7215
|
const existing = listAgents().filter((row) => row.serverUrl === targetServer);
|
|
7168
7216
|
if (existing.length === 0) return;
|
|
7169
|
-
const list = existing.map((row) => ` \u2022 ${
|
|
7170
|
-
console.log(
|
|
7217
|
+
const list = existing.map((row) => ` \u2022 ${import_chalk28.default.cyan(row.agent.did)}${row.agent.name ? import_chalk28.default.dim(` (${row.agent.name})`) : ""}`).join("\n");
|
|
7218
|
+
console.log(import_chalk28.default.yellow("\n\u26A0 ~/.heyarp/agents.json already has agent(s) for this server:"));
|
|
7171
7219
|
console.log(list);
|
|
7172
7220
|
console.log(
|
|
7173
|
-
|
|
7221
|
+
import_chalk28.default.dim(
|
|
7174
7222
|
" After this register completes, you will have multiple local DIDs sharing one state file.\n To keep their state isolated, run with HEYARP_HOME pointing at a per-agent dir, e.g.\n HEYARP_HOME=/tmp/agent-alice heyarp register \u2026\n Otherwise, pass --from-did <did> explicitly on every signed command.\n"
|
|
7175
7223
|
)
|
|
7176
7224
|
);
|
|
@@ -7226,7 +7274,7 @@ function assertJsonRequiresYes(opts) {
|
|
|
7226
7274
|
|
|
7227
7275
|
// src/commands/relationships.ts
|
|
7228
7276
|
var import_sdk26 = require("@heyanon-arp/sdk");
|
|
7229
|
-
var
|
|
7277
|
+
var import_chalk29 = __toESM(require("chalk"));
|
|
7230
7278
|
init_api();
|
|
7231
7279
|
var ALLOWED_STATES2 = new Set(import_sdk26.RELATIONSHIP_STATE_NAMES);
|
|
7232
7280
|
function registerRelationshipsCommand(root) {
|
|
@@ -7255,8 +7303,8 @@ async function runRelationships(positionalDid, opts) {
|
|
|
7255
7303
|
const local = explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("relationships", opts.server, void 0, opts.from);
|
|
7256
7304
|
const did = local.did;
|
|
7257
7305
|
const api = new ArpApiClient(opts.server);
|
|
7258
|
-
progress(opts.json,
|
|
7259
|
-
progress(opts.json,
|
|
7306
|
+
progress(opts.json, import_chalk29.default.dim(`Server: ${api.serverUrl}`));
|
|
7307
|
+
progress(opts.json, import_chalk29.default.dim(`Signer: ${local.did}`));
|
|
7260
7308
|
const query = { limit };
|
|
7261
7309
|
if (state) query.state = state;
|
|
7262
7310
|
const signer = makeSigner(local);
|
|
@@ -7266,18 +7314,18 @@ async function runRelationships(positionalDid, opts) {
|
|
|
7266
7314
|
return;
|
|
7267
7315
|
}
|
|
7268
7316
|
if (rows.length === 0) {
|
|
7269
|
-
console.log(
|
|
7317
|
+
console.log(import_chalk29.default.dim("\n(no relationships)"));
|
|
7270
7318
|
return;
|
|
7271
7319
|
}
|
|
7272
7320
|
console.log("");
|
|
7273
7321
|
console.log(formatRelationshipsTable(rows, did));
|
|
7274
7322
|
if (opts.verbose) {
|
|
7275
|
-
console.log(
|
|
7323
|
+
console.log(import_chalk29.default.bold("\nFull relationships:"));
|
|
7276
7324
|
for (const r of rows) {
|
|
7277
7325
|
console.log(formatJson(r));
|
|
7278
7326
|
}
|
|
7279
7327
|
}
|
|
7280
|
-
console.log(
|
|
7328
|
+
console.log(import_chalk29.default.dim(`
|
|
7281
7329
|
${rows.length} relationship(s).`));
|
|
7282
7330
|
}
|
|
7283
7331
|
function formatRelationshipsTable(rows, selfDid) {
|
|
@@ -7285,7 +7333,7 @@ function formatRelationshipsTable(rows, selfDid) {
|
|
|
7285
7333
|
const data = rows.map((r) => [r.relationshipId, otherPair(r, selfDid), r.state, r.lastEventAt ?? "(none)", String(r.lastEventIndex)]);
|
|
7286
7334
|
const widths = header.map((h, i) => Math.max(h.length, ...data.map((row) => row[i].length)));
|
|
7287
7335
|
const pad = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
7288
|
-
return [
|
|
7336
|
+
return [import_chalk29.default.bold(pad(header)), import_chalk29.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))].join("\n");
|
|
7289
7337
|
}
|
|
7290
7338
|
function otherPair(r, selfDid) {
|
|
7291
7339
|
if (r.pairDidA === selfDid) return r.pairDidB;
|
|
@@ -7310,7 +7358,7 @@ function parseLimit6(raw) {
|
|
|
7310
7358
|
|
|
7311
7359
|
// src/commands/reputation.ts
|
|
7312
7360
|
var import_sdk27 = require("@heyanon-arp/sdk");
|
|
7313
|
-
var
|
|
7361
|
+
var import_chalk30 = __toESM(require("chalk"));
|
|
7314
7362
|
init_api();
|
|
7315
7363
|
function registerReputationCommand(root) {
|
|
7316
7364
|
root.command("reputation").description("Show an agent's informational reputation (composite + component scores + raw counters). Public, no auth. NOT a money/eligibility gate.").argument("<did>", "did:arp:<base58btc> identifier").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the reputation as JSON on stdout.", false).action(async (did, opts) => {
|
|
@@ -7326,10 +7374,10 @@ function registerReputationCommand(root) {
|
|
|
7326
7374
|
const s = rep.scores;
|
|
7327
7375
|
const c = rep.counters;
|
|
7328
7376
|
const j = false;
|
|
7329
|
-
progress(j,
|
|
7377
|
+
progress(j, import_chalk30.default.bold(`Reputation \u2014 ${did}`));
|
|
7330
7378
|
progress(
|
|
7331
7379
|
j,
|
|
7332
|
-
|
|
7380
|
+
import_chalk30.default.dim(` ${rep.informational ? "INFORMATIONAL" : "GATING"} \xB7 ${rep.computed ? `computed ${rep.lastComputedAt}` : "never computed (neutral cold-start)"}`)
|
|
7333
7381
|
);
|
|
7334
7382
|
progress(j, "");
|
|
7335
7383
|
progress(j, ` composite ${bar(s.composite)} ${s.composite.toFixed(2)}`);
|
|
@@ -7337,17 +7385,17 @@ function registerReputationCommand(root) {
|
|
|
7337
7385
|
progress(j, ` settlement ${bar(s.settlement)} ${s.settlement.toFixed(2)}`);
|
|
7338
7386
|
progress(j, ` dispute health ${bar(s.disputeHealth)} ${s.disputeHealth.toFixed(2)}`);
|
|
7339
7387
|
progress(j, "");
|
|
7340
|
-
progress(j,
|
|
7388
|
+
progress(j, import_chalk30.default.dim(" evidence:"));
|
|
7341
7389
|
progress(
|
|
7342
7390
|
j,
|
|
7343
|
-
|
|
7391
|
+
import_chalk30.default.dim(
|
|
7344
7392
|
` on-chain cycles ${c.onchainCycles} \xB7 completed ${c.completedDelegations} (payer ${c.completedAsPayer} / payee ${c.completedAsPayee}) \xB7 failed ${c.failedDelegations}`
|
|
7345
7393
|
)
|
|
7346
7394
|
);
|
|
7347
|
-
progress(j,
|
|
7348
|
-
progress(j,
|
|
7395
|
+
progress(j, import_chalk30.default.dim(` escrows settled ${c.settledEscrows} / refunded ${c.refundedEscrows} \xB7 disputed ${c.disputedEscrows} (adverse ${c.disputesAdverse})`));
|
|
7396
|
+
progress(j, import_chalk30.default.dim(` distinct counterparts ${c.distinctCounterparts} \xB7 active relationships ${c.activeRelationships}`));
|
|
7349
7397
|
progress(j, "");
|
|
7350
|
-
progress(j,
|
|
7398
|
+
progress(j, import_chalk30.default.dim(" Informational only \u2014 a discovery-sort signal, not a money or eligibility gate."));
|
|
7351
7399
|
});
|
|
7352
7400
|
}
|
|
7353
7401
|
function bar(score) {
|
|
@@ -7357,10 +7405,10 @@ function bar(score) {
|
|
|
7357
7405
|
|
|
7358
7406
|
// src/commands/send-handshake.ts
|
|
7359
7407
|
var import_sdk28 = require("@heyanon-arp/sdk");
|
|
7360
|
-
var
|
|
7408
|
+
var import_chalk31 = __toESM(require("chalk"));
|
|
7361
7409
|
init_api();
|
|
7362
7410
|
function registerSendHandshakeCommand(root) {
|
|
7363
|
-
root.command("send-handshake").description("Send a handshake envelope to a recipient (agent name or DID). Server creates the relationship row on first contact.").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--greeting <s>", "Optional greeting text included in body.content").option("--intent <s>", "Optional intent text included in body.content").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk28.MAX_ENVELOPE_TTL_SECONDS} = 24h)`, "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
|
|
7411
|
+
root.command("send-handshake").description("Send a handshake envelope to a recipient (agent name or DID). Server creates the relationship row on first contact.").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--greeting <s>", "Optional greeting text included in body.content").option("--intent <s>", "Optional intent text included in body.content").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk28.MAX_ENVELOPE_TTL_SECONDS} = 24h)`, "3600").option("--require-online", "Abort (exit 1, CLI_RECIPIENT_OFFLINE) if the recipient is not reachable now, instead of warning and sending to their inbox", false).option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
|
|
7364
7412
|
"--json",
|
|
7365
7413
|
"Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, eventId, relationshipId, relationshipEventIndex, serverTimestamp, signedMessageHash, serverEventHash, prevServerEventHash, senderSequence}). The Server/Sender/Recipient prelude moves to stderr so `--json | jq` stays byte-pure. Mutually exclusive with --verbose.",
|
|
7366
7414
|
false
|
|
@@ -7377,10 +7425,11 @@ async function runSendHandshake(recipientDid, opts) {
|
|
|
7377
7425
|
recipientDid = await resolveRecipient(opts.server, "send-handshake", recipientDid, { json: opts.json });
|
|
7378
7426
|
const ttlSeconds = parseTtl3(opts.ttl);
|
|
7379
7427
|
const api = new ArpApiClient(opts.server);
|
|
7380
|
-
progress(opts.json,
|
|
7428
|
+
progress(opts.json, import_chalk31.default.dim(`Server: ${api.serverUrl}`));
|
|
7381
7429
|
const sender = resolveSenderAgent("send-handshake", opts.server, opts.fromDid, opts.from);
|
|
7382
|
-
progress(opts.json,
|
|
7383
|
-
progress(opts.json,
|
|
7430
|
+
progress(opts.json, import_chalk31.default.dim(`Sender: ${sender.did}`));
|
|
7431
|
+
progress(opts.json, import_chalk31.default.dim(`Recipient: ${recipientDid}`));
|
|
7432
|
+
await guardRecipientReachable(api, recipientDid, { requireOnline: opts.requireOnline });
|
|
7384
7433
|
const content = {};
|
|
7385
7434
|
if (opts.greeting) content.greeting = opts.greeting;
|
|
7386
7435
|
if (opts.intent) content.intent = opts.intent;
|
|
@@ -7406,7 +7455,7 @@ async function runSendHandshake(recipientDid, opts) {
|
|
|
7406
7455
|
identitySecretKey: signer.identitySecretKey
|
|
7407
7456
|
});
|
|
7408
7457
|
if (opts.verbose) {
|
|
7409
|
-
console.log(
|
|
7458
|
+
console.log(import_chalk31.default.bold("\nEnvelope (pre-send):"));
|
|
7410
7459
|
console.log(formatJson(envelope));
|
|
7411
7460
|
}
|
|
7412
7461
|
const result = await api.ingest(envelope);
|
|
@@ -7426,23 +7475,23 @@ async function runSendHandshake(recipientDid, opts) {
|
|
|
7426
7475
|
});
|
|
7427
7476
|
return;
|
|
7428
7477
|
}
|
|
7429
|
-
console.log(
|
|
7430
|
-
console.log(`${
|
|
7431
|
-
console.log(`${
|
|
7432
|
-
console.log(`${
|
|
7433
|
-
console.log(`${
|
|
7434
|
-
console.log(`${
|
|
7435
|
-
console.log(`${
|
|
7478
|
+
console.log(import_chalk31.default.green("\nDelivered."));
|
|
7479
|
+
console.log(`${import_chalk31.default.bold("Event id")}: ${import_chalk31.default.cyan(result.eventId)}`);
|
|
7480
|
+
console.log(`${import_chalk31.default.bold("Relationship id")}: ${import_chalk31.default.cyan(result.relationshipId)}`);
|
|
7481
|
+
console.log(`${import_chalk31.default.bold("Chain index")}: ${import_chalk31.default.cyan(String(result.relationshipEventIndex))}`);
|
|
7482
|
+
console.log(`${import_chalk31.default.bold("Server timestamp")}: ${import_chalk31.default.cyan(result.serverTimestamp)}`);
|
|
7483
|
+
console.log(`${import_chalk31.default.bold("Signed message hash")}: ${import_chalk31.default.cyan(result.signedMessageHash)}`);
|
|
7484
|
+
console.log(`${import_chalk31.default.bold("Server event hash")}: ${import_chalk31.default.cyan(result.serverEventHash)}`);
|
|
7436
7485
|
if (result.prevServerEventHash) {
|
|
7437
|
-
console.log(`${
|
|
7486
|
+
console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.cyan(result.prevServerEventHash)}`);
|
|
7438
7487
|
} else {
|
|
7439
|
-
console.log(`${
|
|
7488
|
+
console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.dim("(null \u2014 first event of this relationship)")}`);
|
|
7440
7489
|
}
|
|
7441
7490
|
if (opts.verbose) {
|
|
7442
|
-
console.log(
|
|
7491
|
+
console.log(import_chalk31.default.bold("\nFull server response:"));
|
|
7443
7492
|
console.log(formatJson(result));
|
|
7444
7493
|
}
|
|
7445
|
-
console.log(
|
|
7494
|
+
console.log(import_chalk31.default.dim(`
|
|
7446
7495
|
Local sender_sequence advanced to ${nextSequence}.`));
|
|
7447
7496
|
}
|
|
7448
7497
|
function parseTtl3(raw) {
|
|
@@ -7456,7 +7505,7 @@ function parseTtl3(raw) {
|
|
|
7456
7505
|
|
|
7457
7506
|
// src/commands/send-handshake-response.ts
|
|
7458
7507
|
var import_sdk29 = require("@heyanon-arp/sdk");
|
|
7459
|
-
var
|
|
7508
|
+
var import_chalk32 = __toESM(require("chalk"));
|
|
7460
7509
|
init_api();
|
|
7461
7510
|
var ALLOWED_DECISIONS = new Set(import_sdk29.HANDSHAKE_DECISIONS);
|
|
7462
7511
|
function registerSendHandshakeResponseCommand(root) {
|
|
@@ -7497,11 +7546,11 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7497
7546
|
declinePayload = detail ? { reason, reasonDetail: detail } : { reason };
|
|
7498
7547
|
}
|
|
7499
7548
|
const api = new ArpApiClient(opts.server);
|
|
7500
|
-
progress(opts.json,
|
|
7549
|
+
progress(opts.json, import_chalk32.default.dim(`Server: ${api.serverUrl}`));
|
|
7501
7550
|
const sender = resolveSenderAgent("send-handshake-response", opts.server, opts.fromDid, opts.from);
|
|
7502
|
-
progress(opts.json,
|
|
7503
|
-
progress(opts.json,
|
|
7504
|
-
progress(opts.json,
|
|
7551
|
+
progress(opts.json, import_chalk32.default.dim(`Sender: ${sender.did}`));
|
|
7552
|
+
progress(opts.json, import_chalk32.default.dim(`Recipient: ${recipientDid}`));
|
|
7553
|
+
progress(opts.json, import_chalk32.default.dim(`Decision: ${decision}`));
|
|
7505
7554
|
const signer = makeSigner(sender);
|
|
7506
7555
|
if (!opts.force) {
|
|
7507
7556
|
try {
|
|
@@ -7531,13 +7580,13 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7531
7580
|
});
|
|
7532
7581
|
return;
|
|
7533
7582
|
}
|
|
7534
|
-
progress(opts.json,
|
|
7583
|
+
progress(opts.json, import_chalk32.default.yellow(`
|
|
7535
7584
|
[--idempotency] Relationship ${existing.relationshipId} with ${recipientDid} is already 'active'.`));
|
|
7536
7585
|
progress(
|
|
7537
7586
|
opts.json,
|
|
7538
|
-
|
|
7587
|
+
import_chalk32.default.dim(`A previous accept from this signer (event ${previousResponseFromMe.eventId}) landed successfully. Skipping re-send (use --force to override).`)
|
|
7539
7588
|
);
|
|
7540
|
-
progress(opts.json,
|
|
7589
|
+
progress(opts.json, import_chalk32.default.dim(`Last event index: ${existing.lastEventIndex}, last server event hash: ${existing.lastServerEventHash ?? "(none)"}`));
|
|
7541
7590
|
return;
|
|
7542
7591
|
}
|
|
7543
7592
|
throw new Error(
|
|
@@ -7548,7 +7597,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7548
7597
|
if (probeErr instanceof Error && /CLOSED|terminated|already 'active' from a previous ACCEPT|original initiator/i.test(probeErr.message)) {
|
|
7549
7598
|
throw probeErr;
|
|
7550
7599
|
}
|
|
7551
|
-
progress(opts.json,
|
|
7600
|
+
progress(opts.json, import_chalk32.default.dim(`(idempotency probe failed; proceeding anyway: ${probeErr.message})`));
|
|
7552
7601
|
}
|
|
7553
7602
|
}
|
|
7554
7603
|
const content = { decision };
|
|
@@ -7578,7 +7627,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7578
7627
|
identitySecretKey: signer.identitySecretKey
|
|
7579
7628
|
});
|
|
7580
7629
|
if (opts.verbose) {
|
|
7581
|
-
console.log(
|
|
7630
|
+
console.log(import_chalk32.default.bold("\nEnvelope (pre-send):"));
|
|
7582
7631
|
console.log(formatJson(envelope));
|
|
7583
7632
|
}
|
|
7584
7633
|
const result = await api.ingest(envelope);
|
|
@@ -7599,23 +7648,23 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7599
7648
|
});
|
|
7600
7649
|
return;
|
|
7601
7650
|
}
|
|
7602
|
-
console.log(
|
|
7603
|
-
console.log(`${
|
|
7604
|
-
console.log(`${
|
|
7605
|
-
console.log(`${
|
|
7606
|
-
console.log(`${
|
|
7607
|
-
console.log(`${
|
|
7608
|
-
console.log(`${
|
|
7651
|
+
console.log(import_chalk32.default.green("\nDelivered."));
|
|
7652
|
+
console.log(`${import_chalk32.default.bold("Event id")}: ${import_chalk32.default.cyan(result.eventId)}`);
|
|
7653
|
+
console.log(`${import_chalk32.default.bold("Relationship id")}: ${import_chalk32.default.cyan(result.relationshipId)}`);
|
|
7654
|
+
console.log(`${import_chalk32.default.bold("Chain index")}: ${import_chalk32.default.cyan(String(result.relationshipEventIndex))}`);
|
|
7655
|
+
console.log(`${import_chalk32.default.bold("Server timestamp")}: ${import_chalk32.default.cyan(result.serverTimestamp)}`);
|
|
7656
|
+
console.log(`${import_chalk32.default.bold("Signed message hash")}: ${import_chalk32.default.cyan(result.signedMessageHash)}`);
|
|
7657
|
+
console.log(`${import_chalk32.default.bold("Server event hash")}: ${import_chalk32.default.cyan(result.serverEventHash)}`);
|
|
7609
7658
|
if (result.prevServerEventHash) {
|
|
7610
|
-
console.log(`${
|
|
7659
|
+
console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.cyan(result.prevServerEventHash)}`);
|
|
7611
7660
|
} else {
|
|
7612
|
-
console.log(`${
|
|
7661
|
+
console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.dim("(null \u2014 first event of this relationship)")}`);
|
|
7613
7662
|
}
|
|
7614
7663
|
if (opts.verbose) {
|
|
7615
|
-
console.log(
|
|
7664
|
+
console.log(import_chalk32.default.bold("\nFull server response:"));
|
|
7616
7665
|
console.log(formatJson(result));
|
|
7617
7666
|
}
|
|
7618
|
-
console.log(
|
|
7667
|
+
console.log(import_chalk32.default.dim(`
|
|
7619
7668
|
Local sender_sequence advanced to ${nextSequence}.`));
|
|
7620
7669
|
}
|
|
7621
7670
|
function parseDecision(raw) {
|
|
@@ -7665,8 +7714,64 @@ async function findExistingRelationship(api, signer, senderDid, recipientDid) {
|
|
|
7665
7714
|
return void 0;
|
|
7666
7715
|
}
|
|
7667
7716
|
|
|
7717
|
+
// src/commands/stats.ts
|
|
7718
|
+
var import_chalk33 = __toESM(require("chalk"));
|
|
7719
|
+
init_api();
|
|
7720
|
+
function registerStatsCommand(root) {
|
|
7721
|
+
root.command("stats").description("Show an agent's public stats \u2014 counters, 0..100 scores, derived rates, and settled on-chain volume by asset. Public, no auth.").argument("<agent>", "Agent name (handle) or did:arp:<base58btc>").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the stats as JSON on stdout.", false).action(async (agent, opts) => {
|
|
7722
|
+
const did = await resolveRecipient(opts.server, "stats", agent, { json: opts.json });
|
|
7723
|
+
const api = new ArpApiClient(opts.server);
|
|
7724
|
+
const stats = await api.getStats(did);
|
|
7725
|
+
if (opts.json) {
|
|
7726
|
+
jsonOut(stats);
|
|
7727
|
+
return;
|
|
7728
|
+
}
|
|
7729
|
+
const j = false;
|
|
7730
|
+
const { counters: c, scores: s, rates: r, volume: v } = stats;
|
|
7731
|
+
progress(j, import_chalk33.default.bold(`Stats \u2014 ${did}`));
|
|
7732
|
+
progress(j, import_chalk33.default.dim(` ${stats.computed ? "computed" : "cold-start (no settled cycle yet)"}`));
|
|
7733
|
+
progress(j, "");
|
|
7734
|
+
progress(
|
|
7735
|
+
j,
|
|
7736
|
+
` scores composite ${s.composite.toFixed(0)} \xB7 reliability ${s.reliability.toFixed(0)} \xB7 settlement ${s.settlement.toFixed(0)} \xB7 disputeHealth ${s.disputeHealth.toFixed(0)}`
|
|
7737
|
+
);
|
|
7738
|
+
progress(j, ` rates completion ${pct(r.completionRate)} \xB7 dispute ${pct(r.disputeRate)} \xB7 adverse ${pct(r.adverseDisputeRate)}`);
|
|
7739
|
+
progress(
|
|
7740
|
+
j,
|
|
7741
|
+
` cycles on-chain ${c.onchainCycles} \xB7 completed ${c.completedDelegations} (payer ${c.completedAsPayer} / payee ${c.completedAsPayee}) \xB7 failed ${c.failedDelegations}`
|
|
7742
|
+
);
|
|
7743
|
+
progress(j, ` escrows settled ${c.settledEscrows} / refunded ${c.refundedEscrows} \xB7 disputed ${c.disputedEscrows} (adverse ${c.disputesAdverse})`);
|
|
7744
|
+
progress(j, ` network distinct counterparts ${c.distinctCounterparts} \xB7 active relationships ${c.activeRelationships}`);
|
|
7745
|
+
progress(j, "");
|
|
7746
|
+
progress(j, import_chalk33.default.dim(" earned (as payee):"));
|
|
7747
|
+
renderAssets(v.earnedByAsset);
|
|
7748
|
+
progress(j, import_chalk33.default.dim(" paid (as payer):"));
|
|
7749
|
+
renderAssets(v.paidByAsset);
|
|
7750
|
+
if (v.firstSettledAt || v.lastSettledAt) {
|
|
7751
|
+
progress(j, "");
|
|
7752
|
+
progress(j, import_chalk33.default.dim(` settled span: ${v.firstSettledAt ?? "?"} \u2192 ${v.lastSettledAt ?? "?"}`));
|
|
7753
|
+
}
|
|
7754
|
+
progress(j, "");
|
|
7755
|
+
progress(j, import_chalk33.default.dim(" Public, informational \u2014 derived from on-chain settlement; cached briefly."));
|
|
7756
|
+
});
|
|
7757
|
+
}
|
|
7758
|
+
function pct(r) {
|
|
7759
|
+
return r == null ? "n/a" : `${(r * 100).toFixed(0)}%`;
|
|
7760
|
+
}
|
|
7761
|
+
function renderAssets(assets) {
|
|
7762
|
+
if (assets.length === 0) {
|
|
7763
|
+
progress(false, import_chalk33.default.dim(" (none)"));
|
|
7764
|
+
return;
|
|
7765
|
+
}
|
|
7766
|
+
for (const a of assets) {
|
|
7767
|
+
const label = a.symbol ?? `${a.mint.slice(0, 6)}\u2026`;
|
|
7768
|
+
const amount = a.amountDecimal ?? `${a.amountBaseUnits} base-units`;
|
|
7769
|
+
progress(false, ` ${amount} ${label} ${import_chalk33.default.dim(`(${a.lockCount} lock${a.lockCount === 1 ? "" : "s"})`)}`);
|
|
7770
|
+
}
|
|
7771
|
+
}
|
|
7772
|
+
|
|
7668
7773
|
// src/commands/watch.ts
|
|
7669
|
-
var
|
|
7774
|
+
var import_chalk34 = __toESM(require("chalk"));
|
|
7670
7775
|
init_api();
|
|
7671
7776
|
function registerWatchCommand(root) {
|
|
7672
7777
|
root.command("watch").description("Live tail filtered to a single relationship (SSE). Server-side $match; only envelopes belonging to <rel-id> are streamed.").argument("<relationship-id>", "Relationship UUID to watch").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--verbose", "After each envelope, print the full JSON with a per-row label including eventId + serverEventHash", false).option("--json", "Machine-readable: one NDJSON object per line. Pipe-safe into `jq -c`.", false).option("--full-ids", "Print DIDs + serverEventHash in full (no truncation).", false).action(async (relationshipId, opts) => {
|
|
@@ -7677,9 +7782,9 @@ async function runWatch(relationshipId, opts) {
|
|
|
7677
7782
|
const local = resolveSenderAgent("watch", opts.server, opts.fromDid, opts.from);
|
|
7678
7783
|
const api = new ArpApiClient(opts.server);
|
|
7679
7784
|
if (!opts.json) {
|
|
7680
|
-
console.log(
|
|
7681
|
-
console.log(
|
|
7682
|
-
console.log(
|
|
7785
|
+
console.log(import_chalk34.default.dim(`Server: ${api.serverUrl}`));
|
|
7786
|
+
console.log(import_chalk34.default.dim(`Signer: ${local.did}`));
|
|
7787
|
+
console.log(import_chalk34.default.dim(`Watching: ${relationshipId}`));
|
|
7683
7788
|
}
|
|
7684
7789
|
const controller = new AbortController();
|
|
7685
7790
|
let userAborted = false;
|
|
@@ -7698,7 +7803,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7698
7803
|
}
|
|
7699
7804
|
if (event.type === "heartbeat") continue;
|
|
7700
7805
|
if (event.type === "connected") {
|
|
7701
|
-
console.log(
|
|
7806
|
+
console.log(import_chalk34.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
|
|
7702
7807
|
continue;
|
|
7703
7808
|
}
|
|
7704
7809
|
if (event.type === "envelope") {
|
|
@@ -7712,7 +7817,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7712
7817
|
}
|
|
7713
7818
|
continue;
|
|
7714
7819
|
}
|
|
7715
|
-
console.log(
|
|
7820
|
+
console.log(import_chalk34.default.dim(`(unknown event: ${event.type})`));
|
|
7716
7821
|
}
|
|
7717
7822
|
if (!userAborted) {
|
|
7718
7823
|
throw new Error(`watch ${relationshipId}: stream ended unexpectedly (server may have restarted, or the change stream errored). Re-run to reconnect.`);
|
|
@@ -7720,7 +7825,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7720
7825
|
} catch (err) {
|
|
7721
7826
|
const name = err.name;
|
|
7722
7827
|
if (name === "AbortError" || userAborted) {
|
|
7723
|
-
if (!opts.json) console.log(
|
|
7828
|
+
if (!opts.json) console.log(import_chalk34.default.dim("\nstream closed."));
|
|
7724
7829
|
return;
|
|
7725
7830
|
}
|
|
7726
7831
|
throw err;
|
|
@@ -7734,21 +7839,21 @@ function formatWatchLine(ev, selfDid, opts = {}) {
|
|
|
7734
7839
|
const type = ev.type.padEnd(20);
|
|
7735
7840
|
const direction = directionLabel2(ev, selfDid, opts);
|
|
7736
7841
|
const hash = opts.fullIds ? ev.serverEventHash : hashHead4(ev.serverEventHash);
|
|
7737
|
-
return `${
|
|
7842
|
+
return `${import_chalk34.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk34.default.cyan(hash)}`;
|
|
7738
7843
|
}
|
|
7739
7844
|
function directionLabel2(ev, selfDid, opts = {}) {
|
|
7740
7845
|
const senderHead = opts.fullIds ? ev.senderDid : didHead4(ev.senderDid);
|
|
7741
7846
|
const recipientHead = opts.fullIds ? ev.recipientDid : didHead4(ev.recipientDid);
|
|
7742
|
-
if (ev.senderDid === selfDid) return `${
|
|
7743
|
-
if (ev.recipientDid === selfDid) return `${
|
|
7744
|
-
return `${
|
|
7847
|
+
if (ev.senderDid === selfDid) return `${import_chalk34.default.bold("me")} \u2192 ${import_chalk34.default.dim(recipientHead)}`;
|
|
7848
|
+
if (ev.recipientDid === selfDid) return `${import_chalk34.default.dim(senderHead)} \u2192 ${import_chalk34.default.bold("me")}`;
|
|
7849
|
+
return `${import_chalk34.default.dim(senderHead)} \u2192 ${import_chalk34.default.dim(recipientHead)}`;
|
|
7745
7850
|
}
|
|
7746
7851
|
function didHead4(did) {
|
|
7747
7852
|
if (did.length <= 20) return did;
|
|
7748
7853
|
return `${did.slice(0, 20)}...`;
|
|
7749
7854
|
}
|
|
7750
7855
|
function hashHead4(hash) {
|
|
7751
|
-
if (!hash) return
|
|
7856
|
+
if (!hash) return import_chalk34.default.dim("(none)");
|
|
7752
7857
|
if (hash.length <= 14) return hash;
|
|
7753
7858
|
return `${hash.slice(0, 14)}...`;
|
|
7754
7859
|
}
|
|
@@ -7760,7 +7865,7 @@ function formatClock(iso) {
|
|
|
7760
7865
|
}
|
|
7761
7866
|
|
|
7762
7867
|
// src/commands/whoami.ts
|
|
7763
|
-
var
|
|
7868
|
+
var import_chalk35 = __toESM(require("chalk"));
|
|
7764
7869
|
init_api();
|
|
7765
7870
|
function registerWhoamiCommand(root) {
|
|
7766
7871
|
root.command("whoami").description(
|
|
@@ -7791,12 +7896,12 @@ function registerWhoamiCommand(root) {
|
|
|
7791
7896
|
if (opts.json) {
|
|
7792
7897
|
console.log(formatJson({ ...localJson, account: credential ? { wallet: credential.wallet } : null }));
|
|
7793
7898
|
} else {
|
|
7794
|
-
console.log(
|
|
7795
|
-
console.log(` DID: ${
|
|
7796
|
-
console.log(` Settlement pubkey: ${
|
|
7797
|
-
console.log(` Identity pubkey: ${
|
|
7899
|
+
console.log(import_chalk35.default.bold("Local agent:"));
|
|
7900
|
+
console.log(` DID: ${import_chalk35.default.cyan(local.did)}`);
|
|
7901
|
+
console.log(` Settlement pubkey: ${import_chalk35.default.cyan(local.settlementPublicKeyB58)}`);
|
|
7902
|
+
console.log(` Identity pubkey: ${import_chalk35.default.cyan(local.identityPublicKeyB58)}`);
|
|
7798
7903
|
if (local.name) console.log(` Name: ${local.name}`);
|
|
7799
|
-
console.log(` Account: ${credential ?
|
|
7904
|
+
console.log(` Account: ${credential ? import_chalk35.default.cyan(credential.wallet) : import_chalk35.default.dim("not logged in (heyarp login)")}`);
|
|
7800
7905
|
}
|
|
7801
7906
|
return;
|
|
7802
7907
|
}
|
|
@@ -7814,19 +7919,19 @@ function registerWhoamiCommand(root) {
|
|
|
7814
7919
|
if (opts.json) {
|
|
7815
7920
|
console.log(formatJson({ local: localJson, account, server: agent }));
|
|
7816
7921
|
} else {
|
|
7817
|
-
console.log(
|
|
7818
|
-
console.log(
|
|
7819
|
-
console.log(` DID: ${
|
|
7820
|
-
console.log(` Settlement pubkey: ${
|
|
7821
|
-
console.log(` Identity pubkey: ${
|
|
7822
|
-
console.log(
|
|
7922
|
+
console.log(import_chalk35.default.dim(`Server: ${api.serverUrl}`));
|
|
7923
|
+
console.log(import_chalk35.default.bold("\nLocal agent:"));
|
|
7924
|
+
console.log(` DID: ${import_chalk35.default.cyan(local.did)}`);
|
|
7925
|
+
console.log(` Settlement pubkey: ${import_chalk35.default.cyan(local.settlementPublicKeyB58)}`);
|
|
7926
|
+
console.log(` Identity pubkey: ${import_chalk35.default.cyan(local.identityPublicKeyB58)}`);
|
|
7927
|
+
console.log(import_chalk35.default.bold("\nAccount:"));
|
|
7823
7928
|
if (account) {
|
|
7824
|
-
console.log(` Wallet: ${
|
|
7929
|
+
console.log(` Wallet: ${import_chalk35.default.cyan(account.wallet)}`);
|
|
7825
7930
|
console.log(` Agents registered: ${account.agentCount}`);
|
|
7826
7931
|
} else {
|
|
7827
|
-
console.log(` ${
|
|
7932
|
+
console.log(` ${import_chalk35.default.dim("not logged in (heyarp login)")}`);
|
|
7828
7933
|
}
|
|
7829
|
-
console.log(
|
|
7934
|
+
console.log(import_chalk35.default.bold("\nServer profile:"));
|
|
7830
7935
|
console.log(formatJson(agent));
|
|
7831
7936
|
}
|
|
7832
7937
|
} catch (err) {
|
|
@@ -7838,12 +7943,12 @@ function registerWhoamiCommand(root) {
|
|
|
7838
7943
|
|
|
7839
7944
|
// src/commands/whois.ts
|
|
7840
7945
|
var import_sdk30 = require("@heyanon-arp/sdk");
|
|
7841
|
-
var
|
|
7946
|
+
var import_chalk36 = __toESM(require("chalk"));
|
|
7842
7947
|
init_api();
|
|
7843
7948
|
function registerWhoisCommand(root) {
|
|
7844
7949
|
root.command("whois").description("Resolve an agent name (handle) or DID to its public profile \u2014 DID, description, reputation, liveness.").argument("<name-or-did>", "Agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the full composed profile (DiscoveryProfile) as a single JSON object on stdout.", false).action(async (input, opts) => {
|
|
7845
7950
|
const api = new ArpApiClient(opts.server);
|
|
7846
|
-
progress(opts.json,
|
|
7951
|
+
progress(opts.json, import_chalk36.default.dim(`Server: ${api.serverUrl}`));
|
|
7847
7952
|
const profile = await resolveProfile(api, input);
|
|
7848
7953
|
if (opts.json) {
|
|
7849
7954
|
jsonOut(profile);
|
|
@@ -7866,19 +7971,19 @@ async function resolveProfile(api, input) {
|
|
|
7866
7971
|
return api.discoverByName(name);
|
|
7867
7972
|
}
|
|
7868
7973
|
function printProfile(p) {
|
|
7869
|
-
console.log(`${
|
|
7870
|
-
console.log(`${
|
|
7871
|
-
if (p.description) console.log(`${
|
|
7872
|
-
if (p.tags.length > 0) console.log(`${
|
|
7873
|
-
console.log(`${
|
|
7974
|
+
console.log(`${import_chalk36.default.bold("Name")}: ${import_chalk36.default.cyan(p.name ?? "(unnamed)")}`);
|
|
7975
|
+
console.log(`${import_chalk36.default.bold("DID")}: ${import_chalk36.default.cyan(p.did)}`);
|
|
7976
|
+
if (p.description) console.log(`${import_chalk36.default.bold("Description")}: ${p.description}`);
|
|
7977
|
+
if (p.tags.length > 0) console.log(`${import_chalk36.default.bold("Tags")}: ${p.tags.join(", ")}`);
|
|
7978
|
+
console.log(`${import_chalk36.default.bold("Registered")}: ${p.registeredAt}`);
|
|
7874
7979
|
const rep = p.reputation;
|
|
7875
|
-
console.log(`${
|
|
7876
|
-
console.log(`${
|
|
7980
|
+
console.log(`${import_chalk36.default.bold("Reputation")}: composite ${rep.scores.composite}/100${rep.computed ? "" : import_chalk36.default.dim(" (cold-start \u2014 no settled cycles yet)")}`);
|
|
7981
|
+
console.log(`${import_chalk36.default.bold("Online")}: ${p.liveness.online ? import_chalk36.default.green("yes") : import_chalk36.default.dim("no")}`);
|
|
7877
7982
|
}
|
|
7878
7983
|
|
|
7879
7984
|
// src/commands/work.ts
|
|
7880
7985
|
var import_sdk31 = require("@heyanon-arp/sdk");
|
|
7881
|
-
var
|
|
7986
|
+
var import_chalk37 = __toESM(require("chalk"));
|
|
7882
7987
|
init_api();
|
|
7883
7988
|
function registerWorkCommands(root) {
|
|
7884
7989
|
const cmd = root.command("work").description("Work envelopes inside an ACCEPTED delegation: request / respond");
|
|
@@ -7919,11 +8024,11 @@ async function runRequest(recipientDid, delegationId, opts) {
|
|
|
7919
8024
|
params
|
|
7920
8025
|
};
|
|
7921
8026
|
const body = { type: "work_request", content };
|
|
7922
|
-
progress(opts.json,
|
|
7923
|
-
progress(opts.json,
|
|
7924
|
-
progress(opts.json,
|
|
7925
|
-
progress(opts.json,
|
|
7926
|
-
progress(opts.json,
|
|
8027
|
+
progress(opts.json, import_chalk37.default.dim(`Server: ${api.serverUrl}`));
|
|
8028
|
+
progress(opts.json, import_chalk37.default.dim(`Sender: ${sender.did}`));
|
|
8029
|
+
progress(opts.json, import_chalk37.default.dim(`Recipient: ${recipientDid}`));
|
|
8030
|
+
progress(opts.json, import_chalk37.default.dim(`Delegation: ${delegationId}`));
|
|
8031
|
+
progress(opts.json, import_chalk37.default.dim(`Request id: ${requestId}`));
|
|
7927
8032
|
const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
7928
8033
|
if (opts.json) {
|
|
7929
8034
|
jsonOut({
|
|
@@ -7940,10 +8045,10 @@ async function runRequest(recipientDid, delegationId, opts) {
|
|
|
7940
8045
|
});
|
|
7941
8046
|
} else {
|
|
7942
8047
|
printIngestResult3(result);
|
|
7943
|
-
console.log(
|
|
8048
|
+
console.log(import_chalk37.default.dim(`
|
|
7944
8049
|
The payee can reply with:`));
|
|
7945
|
-
console.log(
|
|
7946
|
-
console.log(
|
|
8050
|
+
console.log(import_chalk37.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
|
|
8051
|
+
console.log(import_chalk37.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
|
|
7947
8052
|
}
|
|
7948
8053
|
}
|
|
7949
8054
|
function registerRespond(parent) {
|
|
@@ -7978,13 +8083,13 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
|
|
|
7978
8083
|
...responsePayload
|
|
7979
8084
|
};
|
|
7980
8085
|
const body = { type: "work_response", content };
|
|
7981
|
-
progress(opts.json,
|
|
7982
|
-
progress(opts.json,
|
|
7983
|
-
progress(opts.json,
|
|
7984
|
-
progress(opts.json,
|
|
7985
|
-
progress(opts.json,
|
|
7986
|
-
progress(opts.json,
|
|
7987
|
-
progress(opts.json,
|
|
8086
|
+
progress(opts.json, import_chalk37.default.dim(`Server: ${api.serverUrl}`));
|
|
8087
|
+
progress(opts.json, import_chalk37.default.dim(`Sender: ${sender.did}`));
|
|
8088
|
+
progress(opts.json, import_chalk37.default.dim(`Recipient: ${recipientDid}`));
|
|
8089
|
+
progress(opts.json, import_chalk37.default.dim(`Relationship: ${relationshipId}`));
|
|
8090
|
+
progress(opts.json, import_chalk37.default.dim(`Delegation: ${delegationId}`));
|
|
8091
|
+
progress(opts.json, import_chalk37.default.dim(`Request id: ${requestId}`));
|
|
8092
|
+
progress(opts.json, import_chalk37.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
|
|
7988
8093
|
const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
7989
8094
|
if (opts.json) {
|
|
7990
8095
|
jsonOut({
|
|
@@ -8025,7 +8130,7 @@ async function sendWorkEnvelope(args) {
|
|
|
8025
8130
|
identitySecretKey: signer.identitySecretKey
|
|
8026
8131
|
});
|
|
8027
8132
|
if (args.verbose) {
|
|
8028
|
-
console.log(
|
|
8133
|
+
console.log(import_chalk37.default.bold("\nEnvelope (pre-send):"));
|
|
8029
8134
|
console.log(formatJson(envelope));
|
|
8030
8135
|
}
|
|
8031
8136
|
try {
|
|
@@ -8065,12 +8170,12 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
|
|
|
8065
8170
|
);
|
|
8066
8171
|
}
|
|
8067
8172
|
function printIngestResult3(result) {
|
|
8068
|
-
console.log(
|
|
8069
|
-
console.log(`${
|
|
8070
|
-
console.log(`${
|
|
8071
|
-
console.log(`${
|
|
8072
|
-
console.log(`${
|
|
8073
|
-
console.log(`${
|
|
8173
|
+
console.log(import_chalk37.default.green("\nDelivered."));
|
|
8174
|
+
console.log(`${import_chalk37.default.bold("Event id")}: ${import_chalk37.default.cyan(result.eventId)}`);
|
|
8175
|
+
console.log(`${import_chalk37.default.bold("Relationship id")}: ${import_chalk37.default.cyan(result.relationshipId)}`);
|
|
8176
|
+
console.log(`${import_chalk37.default.bold("Chain index")}: ${import_chalk37.default.cyan(String(result.relationshipEventIndex))}`);
|
|
8177
|
+
console.log(`${import_chalk37.default.bold("Server timestamp")}: ${import_chalk37.default.cyan(result.serverTimestamp)}`);
|
|
8178
|
+
console.log(`${import_chalk37.default.bold("Server event hash")}: ${import_chalk37.default.cyan(result.serverEventHash)}`);
|
|
8074
8179
|
}
|
|
8075
8180
|
function parseJsonObject(cmdName, flagName, raw) {
|
|
8076
8181
|
let parsed;
|
|
@@ -8172,7 +8277,7 @@ function parseRequestId(cmdName, raw) {
|
|
|
8172
8277
|
|
|
8173
8278
|
// src/commands/work-list.ts
|
|
8174
8279
|
var import_sdk32 = require("@heyanon-arp/sdk");
|
|
8175
|
-
var
|
|
8280
|
+
var import_chalk38 = __toESM(require("chalk"));
|
|
8176
8281
|
init_api();
|
|
8177
8282
|
var ALLOWED_STATES3 = new Set(import_sdk32.WORK_LOG_STATES);
|
|
8178
8283
|
function registerWorkListCommand(root) {
|
|
@@ -8199,9 +8304,9 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8199
8304
|
const api = new ArpApiClient(opts.server);
|
|
8200
8305
|
const sender = resolveSenderAgent("work-list", opts.server, opts.fromDid, opts.from);
|
|
8201
8306
|
if (!opts.json) {
|
|
8202
|
-
console.log(
|
|
8203
|
-
console.log(
|
|
8204
|
-
console.log(
|
|
8307
|
+
console.log(import_chalk38.default.dim(`Server: ${api.serverUrl}`));
|
|
8308
|
+
console.log(import_chalk38.default.dim(`Signer: ${sender.did}`));
|
|
8309
|
+
console.log(import_chalk38.default.dim(`Relationship: ${relationshipId}`));
|
|
8205
8310
|
}
|
|
8206
8311
|
const query = { limit };
|
|
8207
8312
|
if (state) query.state = state;
|
|
@@ -8214,7 +8319,7 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8214
8319
|
return;
|
|
8215
8320
|
}
|
|
8216
8321
|
if (rows.length === 0) {
|
|
8217
|
-
console.log(
|
|
8322
|
+
console.log(import_chalk38.default.dim("\n(no work-logs for this relationship)"));
|
|
8218
8323
|
return;
|
|
8219
8324
|
}
|
|
8220
8325
|
console.log("");
|
|
@@ -8231,36 +8336,36 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8231
8336
|
}));
|
|
8232
8337
|
}
|
|
8233
8338
|
const lastId = rows[rows.length - 1].id;
|
|
8234
|
-
console.log(
|
|
8339
|
+
console.log(import_chalk38.default.dim(`
|
|
8235
8340
|
${rows.length} work-log row(s). Paginate with --after ${lastId}.`));
|
|
8236
8341
|
}
|
|
8237
8342
|
function formatWorkLogLine(w, selfDid, opts = {}) {
|
|
8238
8343
|
const delegationPart = opts.fullIds ? w.delegationId : idHead3(w.delegationId);
|
|
8239
8344
|
const requestPart = opts.fullIds ? w.requestId : truncate3(w.requestId, 16);
|
|
8240
|
-
const id =
|
|
8345
|
+
const id = import_chalk38.default.bold(`${delegationPart}/${requestPart}`);
|
|
8241
8346
|
const state = colorState2(w.state).padEnd(stateColumnWidth2());
|
|
8242
8347
|
const peerCallerHead = opts.fullIds ? w.callerDid : didHead5(w.callerDid);
|
|
8243
8348
|
const peerPayeeHead = opts.fullIds ? w.payeeDid : didHead5(w.payeeDid);
|
|
8244
|
-
const direction = w.callerDid === selfDid ? `${
|
|
8349
|
+
const direction = w.callerDid === selfDid ? `${import_chalk38.default.bold("me")} \u2192 ${import_chalk38.default.dim(peerPayeeHead)}` : `${import_chalk38.default.dim(peerCallerHead)} \u2192 ${import_chalk38.default.bold("me")}`;
|
|
8245
8350
|
const outcome = formatOutcome(w);
|
|
8246
8351
|
return `${id} ${state} ${direction} ${outcome}`;
|
|
8247
8352
|
}
|
|
8248
8353
|
function colorState2(s) {
|
|
8249
8354
|
switch (s) {
|
|
8250
8355
|
case import_sdk32.WorkLogStates.REQUESTED:
|
|
8251
|
-
return
|
|
8356
|
+
return import_chalk38.default.yellow("requested");
|
|
8252
8357
|
case import_sdk32.WorkLogStates.RESPONDED:
|
|
8253
|
-
return
|
|
8358
|
+
return import_chalk38.default.green("responded");
|
|
8254
8359
|
}
|
|
8255
8360
|
}
|
|
8256
8361
|
function stateColumnWidth2() {
|
|
8257
8362
|
return 9;
|
|
8258
8363
|
}
|
|
8259
8364
|
function formatOutcome(w) {
|
|
8260
|
-
if (w.state === import_sdk32.WorkLogStates.REQUESTED) return
|
|
8261
|
-
if (w.responseError) return
|
|
8262
|
-
if (w.responseOutput) return
|
|
8263
|
-
return
|
|
8365
|
+
if (w.state === import_sdk32.WorkLogStates.REQUESTED) return import_chalk38.default.dim("(in flight)");
|
|
8366
|
+
if (w.responseError) return import_chalk38.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
|
|
8367
|
+
if (w.responseOutput) return import_chalk38.default.cyan("ok");
|
|
8368
|
+
return import_chalk38.default.dim("(empty response)");
|
|
8264
8369
|
}
|
|
8265
8370
|
function idHead3(id) {
|
|
8266
8371
|
if (id.length <= 12) return id;
|
|
@@ -8462,6 +8567,7 @@ async function main() {
|
|
|
8462
8567
|
registerReceiptCommands(program);
|
|
8463
8568
|
registerReceiptsCommand(program);
|
|
8464
8569
|
registerReputationCommand(program);
|
|
8570
|
+
registerStatsCommand(program);
|
|
8465
8571
|
registerWalletCommands(program);
|
|
8466
8572
|
(0, import_shield3.installMiddleware)(program);
|
|
8467
8573
|
try {
|