@heyanon-arp/cli 0.0.17 → 0.0.18
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 +861 -727
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -345,6 +345,10 @@ var init_api = __esm({
|
|
|
345
345
|
async discoverProfile(did) {
|
|
346
346
|
return this.get(`/v1/discovery/agents/${encodeURIComponent(did)}/profile`);
|
|
347
347
|
}
|
|
348
|
+
/** Public `GET /v1/discovery/agents/by-name/:name`. Resolves a unique name → composed profile (incl. DID). 404 if unknown. */
|
|
349
|
+
async discoverByName(name) {
|
|
350
|
+
return this.get(`/v1/discovery/agents/by-name/${encodeURIComponent(name)}`);
|
|
351
|
+
}
|
|
348
352
|
/**
|
|
349
353
|
* Public `GET /v1/escrow/config`. Returns the live on-chain V2
|
|
350
354
|
* Config PDA (fees / pause / stakes / windows). No auth.
|
|
@@ -722,7 +726,7 @@ var import_simple_update_notifier = __toESM(require("simple-update-notifier"));
|
|
|
722
726
|
// package.json
|
|
723
727
|
var package_default = {
|
|
724
728
|
name: "@heyanon-arp/cli",
|
|
725
|
-
version: "0.0.
|
|
729
|
+
version: "0.0.18",
|
|
726
730
|
description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
|
|
727
731
|
license: "MIT",
|
|
728
732
|
keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
|
|
@@ -767,7 +771,7 @@ var package_default = {
|
|
|
767
771
|
};
|
|
768
772
|
|
|
769
773
|
// src/commands/agents.ts
|
|
770
|
-
var
|
|
774
|
+
var import_sdk3 = require("@heyanon-arp/sdk");
|
|
771
775
|
var import_chalk3 = __toESM(require("chalk"));
|
|
772
776
|
init_api();
|
|
773
777
|
|
|
@@ -912,6 +916,7 @@ function formatAgentsTable(rows) {
|
|
|
912
916
|
// src/state.ts
|
|
913
917
|
var import_node_fs3 = require("fs");
|
|
914
918
|
var import_node_path4 = require("path");
|
|
919
|
+
var import_sdk2 = require("@heyanon-arp/sdk");
|
|
915
920
|
init_api();
|
|
916
921
|
|
|
917
922
|
// src/credentials.ts
|
|
@@ -1140,9 +1145,25 @@ function warnIfForeignOwner(agent, serverUrl) {
|
|
|
1140
1145
|
function resolveSenderAgent(cmdName, serverOverride, explicitFromDid) {
|
|
1141
1146
|
const resolvedServerUrl = resolveServerUrl(serverOverride);
|
|
1142
1147
|
if (explicitFromDid) {
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1148
|
+
if (explicitFromDid.startsWith("did:arp:")) {
|
|
1149
|
+
const agent = loadAgentOrThrow(serverOverride, explicitFromDid);
|
|
1150
|
+
warnIfForeignOwner(agent, resolvedServerUrl);
|
|
1151
|
+
return agent;
|
|
1152
|
+
}
|
|
1153
|
+
const wanted = (0, import_sdk2.normalizeName)(explicitFromDid);
|
|
1154
|
+
const named = listAgents().filter((row) => row.serverUrl === resolvedServerUrl && row.agent.name === wanted);
|
|
1155
|
+
if (named.length === 1) {
|
|
1156
|
+
warnIfForeignOwner(named[0].agent, resolvedServerUrl);
|
|
1157
|
+
return named[0].agent;
|
|
1158
|
+
}
|
|
1159
|
+
if (named.length === 0) {
|
|
1160
|
+
throw new Error(`${cmdName}: no local agent named '${wanted}' for ${resolvedServerUrl}. Pass its did:arp: DID, or register/recover that agent locally first.`);
|
|
1161
|
+
}
|
|
1162
|
+
const dups = named.map((row) => ` ${row.agent.did}`).join("\n");
|
|
1163
|
+
throw new Error(
|
|
1164
|
+
`${cmdName}: ${named.length} local agents share the name '${wanted}' for ${resolvedServerUrl} \u2014 ambiguous. Pass the did:arp: DID instead. Candidates:
|
|
1165
|
+
${dups}`
|
|
1166
|
+
);
|
|
1146
1167
|
}
|
|
1147
1168
|
const onServer = listAgents().filter((row) => row.serverUrl === resolvedServerUrl);
|
|
1148
1169
|
if (onServer.length === 1) {
|
|
@@ -1173,7 +1194,7 @@ function listAgents() {
|
|
|
1173
1194
|
var import_chalk2 = __toESM(require("chalk"));
|
|
1174
1195
|
init_api();
|
|
1175
1196
|
function registerLifecycleCommands(root) {
|
|
1176
|
-
root.command("update").description("Update an agent profile (
|
|
1197
|
+
root.command("update").description("Update an agent profile (description / tags). At least one flag is required. The agent name is immutable and cannot be changed.").argument("[did]", "Agent DID (did:arp:...) \u2014 optional when --from-did is given OR exactly one agent is registered for the resolved server.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Alias for the positional <did> \u2014 accepted for consistency with other signed commands. Must match the positional if both are given.").option("--description <s>", "New description").option("--tag <s>", "Capability tag \u2014 REPLACES the existing list. Repeatable: --tag translation --tag fr", accumulate, []).option("--clear-tags", "Drop all tags (cannot be combined with --tag)", false).option("--json", "Machine-readable mode \u2014 emit the updated profile as a single JSON object on stdout (AgentPublic). Prelude moves to stderr. ", false).action(
|
|
1177
1198
|
async (did, opts) => {
|
|
1178
1199
|
if (did !== void 0 && opts.fromDid !== void 0 && did !== opts.fromDid) {
|
|
1179
1200
|
throw new Error(`update: positional <did> (${did}) and --from-did (${opts.fromDid}) disagree \u2014 pass only one`);
|
|
@@ -1182,7 +1203,7 @@ function registerLifecycleCommands(root) {
|
|
|
1182
1203
|
const targetDid = (explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("update", opts.server, void 0)).did;
|
|
1183
1204
|
const body = buildUpdateBody(opts);
|
|
1184
1205
|
if (Object.keys(body).length === 0) {
|
|
1185
|
-
throw new Error("update: pass at least one of --
|
|
1206
|
+
throw new Error("update: pass at least one of --description / --tag / --clear-tags");
|
|
1186
1207
|
}
|
|
1187
1208
|
const agent = await actSigned(targetDid, opts.server, opts.json, (api, signer) => api.updateAgent(targetDid, body, signer));
|
|
1188
1209
|
updateAgentLocal(opts.server, targetDid, {
|
|
@@ -1206,7 +1227,6 @@ function buildUpdateBody(opts) {
|
|
|
1206
1227
|
throw new Error("update: --clear-tags cannot be combined with --tag");
|
|
1207
1228
|
}
|
|
1208
1229
|
const body = {};
|
|
1209
|
-
if (opts.name !== void 0) body.name = opts.name;
|
|
1210
1230
|
if (opts.description !== void 0) body.description = opts.description;
|
|
1211
1231
|
if (opts.clearTags) {
|
|
1212
1232
|
body.tags = [];
|
|
@@ -1265,10 +1285,10 @@ function registerAgentsCommand(root) {
|
|
|
1265
1285
|
}
|
|
1266
1286
|
async function runAgents(opts) {
|
|
1267
1287
|
const limit = parseLimit(opts.limit);
|
|
1268
|
-
if (opts.sort && opts.sort !==
|
|
1288
|
+
if (opts.sort && opts.sort !== import_sdk3.DiscoverySorts.REPUTATION && opts.sort !== import_sdk3.DiscoverySorts.RECENT && opts.sort !== import_sdk3.DiscoverySorts.CREATED) {
|
|
1269
1289
|
throw new Error(`agents: --sort must be 'reputation', 'recent', or 'created' (got '${opts.sort}')`);
|
|
1270
1290
|
}
|
|
1271
|
-
const sort = opts.sort ===
|
|
1291
|
+
const sort = opts.sort === import_sdk3.DiscoverySorts.RECENT ? import_sdk3.DiscoverySorts.RECENT : opts.sort === import_sdk3.DiscoverySorts.CREATED ? import_sdk3.DiscoverySorts.CREATED : import_sdk3.DiscoverySorts.REPUTATION;
|
|
1272
1292
|
const api = new ArpApiClient(opts.server);
|
|
1273
1293
|
progress(opts.json, import_chalk3.default.dim(`Server: ${api.serverUrl}`));
|
|
1274
1294
|
const query = { limit, sort };
|
|
@@ -1277,7 +1297,7 @@ async function runAgents(opts) {
|
|
|
1277
1297
|
if (opts.accountId) query.accountId = opts.accountId;
|
|
1278
1298
|
if (opts.accepts) query.accepts = resolveAcceptsAsset(opts.accepts);
|
|
1279
1299
|
if (opts.online) query.online = true;
|
|
1280
|
-
if (sort ===
|
|
1300
|
+
if (sort === import_sdk3.DiscoverySorts.CREATED) {
|
|
1281
1301
|
if (opts.after) query.after = opts.after;
|
|
1282
1302
|
} else {
|
|
1283
1303
|
query.page = parsePage(opts.page);
|
|
@@ -1316,10 +1336,10 @@ ${rule}`);
|
|
|
1316
1336
|
`);
|
|
1317
1337
|
}
|
|
1318
1338
|
if (pagination.hasMore) {
|
|
1319
|
-
if (sort ===
|
|
1339
|
+
if (sort === import_sdk3.DiscoverySorts.CREATED && pagination.nextCursor) {
|
|
1320
1340
|
console.log(import_chalk3.default.dim(`
|
|
1321
1341
|
Next page: re-run with --after ${pagination.nextCursor}`));
|
|
1322
|
-
} else if (sort !==
|
|
1342
|
+
} else if (sort !== import_sdk3.DiscoverySorts.CREATED) {
|
|
1323
1343
|
console.log(import_chalk3.default.dim(`
|
|
1324
1344
|
Next page: re-run with --page ${parsePage(opts.page) + 1}`));
|
|
1325
1345
|
}
|
|
@@ -1358,7 +1378,7 @@ function parsePage(raw) {
|
|
|
1358
1378
|
return n;
|
|
1359
1379
|
}
|
|
1360
1380
|
function resolveAcceptsAsset(input) {
|
|
1361
|
-
const resolved = (0,
|
|
1381
|
+
const resolved = (0, import_sdk3.resolveAsset)(input);
|
|
1362
1382
|
if (!resolved) {
|
|
1363
1383
|
throw new Error(`agents: --accepts '${input}' is not a known asset shorthand or a valid CAIP-19 id.`);
|
|
1364
1384
|
}
|
|
@@ -1487,11 +1507,11 @@ function printAcceptPrefs(prefs) {
|
|
|
1487
1507
|
}
|
|
1488
1508
|
|
|
1489
1509
|
// src/commands/assets.ts
|
|
1490
|
-
var
|
|
1510
|
+
var import_sdk4 = require("@heyanon-arp/sdk");
|
|
1491
1511
|
var import_chalk4 = __toESM(require("chalk"));
|
|
1492
1512
|
function renderAssetsText() {
|
|
1493
1513
|
const lines = [];
|
|
1494
|
-
for (const [cluster, assets] of Object.entries(
|
|
1514
|
+
for (const [cluster, assets] of Object.entries(import_sdk4.ASSET_WHITELIST)) {
|
|
1495
1515
|
lines.push(import_chalk4.default.bold(cluster));
|
|
1496
1516
|
for (const a of assets) {
|
|
1497
1517
|
const key = `${a.symbol}:${cluster}`;
|
|
@@ -1507,7 +1527,7 @@ function renderAssetsText() {
|
|
|
1507
1527
|
function registerAssetsCommand(root) {
|
|
1508
1528
|
root.command("assets").description("List the payment-asset whitelist (per cluster) \u2014 currencies the server accepts for delegations").option("--json", "machine-readable output (the per-cluster whitelist table)").action((opts) => {
|
|
1509
1529
|
if (opts.json) {
|
|
1510
|
-
console.log(formatJson(
|
|
1530
|
+
console.log(formatJson(import_sdk4.ASSET_WHITELIST));
|
|
1511
1531
|
return;
|
|
1512
1532
|
}
|
|
1513
1533
|
console.log(renderAssetsText());
|
|
@@ -1515,14 +1535,14 @@ function registerAssetsCommand(root) {
|
|
|
1515
1535
|
}
|
|
1516
1536
|
|
|
1517
1537
|
// src/commands/block.ts
|
|
1518
|
-
var
|
|
1538
|
+
var import_sdk5 = require("@heyanon-arp/sdk");
|
|
1519
1539
|
var import_chalk5 = __toESM(require("chalk"));
|
|
1520
1540
|
init_api();
|
|
1521
1541
|
function resolveSigningAgent(opts) {
|
|
1522
1542
|
return opts.fromDid !== void 0 ? loadAgentOrThrow(opts.server, opts.fromDid) : resolveSenderAgent("block", opts.server, void 0);
|
|
1523
1543
|
}
|
|
1524
1544
|
function formatBlockRow(b) {
|
|
1525
|
-
const scope = b.scope ===
|
|
1545
|
+
const scope = b.scope === import_sdk5.InboxBlockScopes.ACCOUNT ? import_chalk5.default.yellow("account") : import_chalk5.default.cyan("did");
|
|
1526
1546
|
const reason = b.reason ? import_chalk5.default.dim(` \u2014 ${b.reason}`) : "";
|
|
1527
1547
|
return `${scope.padEnd(7)} ${b.did}${reason} ${import_chalk5.default.dim(b.blockedAt)}`;
|
|
1528
1548
|
}
|
|
@@ -1547,7 +1567,7 @@ async function runAdd(did, opts) {
|
|
|
1547
1567
|
jsonOut(result);
|
|
1548
1568
|
return;
|
|
1549
1569
|
}
|
|
1550
|
-
const what = result.scope ===
|
|
1570
|
+
const what = result.scope === import_sdk5.InboxBlockScopes.ACCOUNT ? `the owner account of ${did} (all its agents)` : did;
|
|
1551
1571
|
console.log(import_chalk5.default.green(`\u2713 Blocked ${what}.`));
|
|
1552
1572
|
}
|
|
1553
1573
|
async function runRemove(did, opts) {
|
|
@@ -1663,15 +1683,15 @@ function unknownKey(key) {
|
|
|
1663
1683
|
|
|
1664
1684
|
// src/commands/delegation.ts
|
|
1665
1685
|
var import_node_fs4 = require("fs");
|
|
1666
|
-
var
|
|
1667
|
-
var
|
|
1686
|
+
var import_sdk12 = require("@heyanon-arp/sdk");
|
|
1687
|
+
var import_chalk9 = __toESM(require("chalk"));
|
|
1668
1688
|
init_api();
|
|
1669
1689
|
|
|
1670
1690
|
// src/id-format.ts
|
|
1671
|
-
var
|
|
1691
|
+
var import_sdk6 = require("@heyanon-arp/sdk");
|
|
1672
1692
|
var UUID_RE = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
|
|
1673
1693
|
var OBJECT_ID_24_HEX_RE = /^[0-9a-f]{24}$/;
|
|
1674
|
-
var SHA256_PREFIX_RE =
|
|
1694
|
+
var SHA256_PREFIX_RE = import_sdk6.SHA256_HEX_RE;
|
|
1675
1695
|
var UUID_NO_DASHES_RE = /^[a-fA-F0-9]{32}$/;
|
|
1676
1696
|
function describeNonUuidShape(raw) {
|
|
1677
1697
|
if (raw === "") return "empty string";
|
|
@@ -1702,10 +1722,31 @@ function requireUuid(cmdName, raw, label) {
|
|
|
1702
1722
|
throw new Error(hint ? `${base} \u2014 ${hint}` : base);
|
|
1703
1723
|
}
|
|
1704
1724
|
|
|
1705
|
-
// src/
|
|
1706
|
-
var
|
|
1725
|
+
// src/resolve-recipient.ts
|
|
1726
|
+
var import_sdk7 = require("@heyanon-arp/sdk");
|
|
1707
1727
|
var import_chalk7 = __toESM(require("chalk"));
|
|
1708
1728
|
init_api();
|
|
1729
|
+
async function resolveRecipient(serverOverride, cmdName, input, opts = {}) {
|
|
1730
|
+
if (input.startsWith("did:arp:")) {
|
|
1731
|
+
if (!(0, import_sdk7.isValidDid)(input)) {
|
|
1732
|
+
throw new Error(`${cmdName}: '${input}' starts with did:arp: but is not a valid DID (base58btc-encoded 32-byte Ed25519 pubkey).`);
|
|
1733
|
+
}
|
|
1734
|
+
return input;
|
|
1735
|
+
}
|
|
1736
|
+
const name = (0, import_sdk7.normalizeName)(input);
|
|
1737
|
+
if (!(0, import_sdk7.isValidAgentName)(name)) {
|
|
1738
|
+
throw new Error(`${cmdName}: '${input}' is neither a DID (did:arp:...) nor a valid agent name (lowercase a-z0-9_, 3-32 chars).`);
|
|
1739
|
+
}
|
|
1740
|
+
const api = new ArpApiClient(serverOverride);
|
|
1741
|
+
const profile = await api.discoverByName(name);
|
|
1742
|
+
warn(opts.json, import_chalk7.default.dim(`Resolved ${import_chalk7.default.cyan(name)} \u2192 ${profile.did}${profile.description ? ` (${profile.description})` : ""}`));
|
|
1743
|
+
return profile.did;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
// src/commands/status.ts
|
|
1747
|
+
var import_sdk8 = require("@heyanon-arp/sdk");
|
|
1748
|
+
var import_chalk8 = __toESM(require("chalk"));
|
|
1749
|
+
init_api();
|
|
1709
1750
|
var UNTIL_PHASES = [
|
|
1710
1751
|
"delegation.offered",
|
|
1711
1752
|
"delegation.accepted",
|
|
@@ -1753,9 +1794,9 @@ async function runStatus(relationshipId, opts) {
|
|
|
1753
1794
|
const api = new ArpApiClient(opts.server);
|
|
1754
1795
|
const sender = resolveSenderAgent("status", opts.server, opts.fromDid);
|
|
1755
1796
|
if (!opts.json) {
|
|
1756
|
-
console.log(
|
|
1757
|
-
console.log(
|
|
1758
|
-
console.log(
|
|
1797
|
+
console.log(import_chalk8.default.dim(`Server: ${api.serverUrl}`));
|
|
1798
|
+
console.log(import_chalk8.default.dim(`Signer: ${sender.did}`));
|
|
1799
|
+
console.log(import_chalk8.default.dim(`Relationship: ${relationshipId}`));
|
|
1759
1800
|
}
|
|
1760
1801
|
const signer = makeSigner(sender);
|
|
1761
1802
|
if (!opts.wait) {
|
|
@@ -1787,7 +1828,7 @@ async function runStatus(relationshipId, opts) {
|
|
|
1787
1828
|
async function awaitFsmTransitionAfterAction(input) {
|
|
1788
1829
|
const { api, signerDid, signer, relationshipId, untilPhase, waitIntervalSec, waitTimeoutSec, waitVerbose, json } = input;
|
|
1789
1830
|
if (!json) {
|
|
1790
|
-
console.log(
|
|
1831
|
+
console.log(import_chalk8.default.dim(`
|
|
1791
1832
|
[--wait-until ${untilPhase}] polling relationship ${relationshipId} (interval=${waitIntervalSec}s timeout=${waitTimeoutSec}s)`));
|
|
1792
1833
|
}
|
|
1793
1834
|
const outcome = await runWaitLoop({
|
|
@@ -1804,13 +1845,13 @@ async function awaitFsmTransitionAfterAction(input) {
|
|
|
1804
1845
|
}
|
|
1805
1846
|
}
|
|
1806
1847
|
async function runWaitLoop(opts) {
|
|
1807
|
-
const isTerminal = (s) => s.cycleComplete || s.relationshipState ===
|
|
1848
|
+
const isTerminal = (s) => s.cycleComplete || s.relationshipState === import_sdk8.RelationshipStates.CLOSED || s.relationshipState === "not_found";
|
|
1808
1849
|
const isActionable = (s) => {
|
|
1809
1850
|
if (s.nextActionOwner === "me") {
|
|
1810
1851
|
if (s.relationshipState === "unknown") return false;
|
|
1811
1852
|
return true;
|
|
1812
1853
|
}
|
|
1813
|
-
if (s.nextActionOwner === "either" && s.relationshipState ===
|
|
1854
|
+
if (s.nextActionOwner === "either" && s.relationshipState === import_sdk8.RelationshipStates.ACTIVE) {
|
|
1814
1855
|
return true;
|
|
1815
1856
|
}
|
|
1816
1857
|
return false;
|
|
@@ -1826,7 +1867,7 @@ async function runWaitLoop(opts) {
|
|
|
1826
1867
|
}
|
|
1827
1868
|
if (isUntilReached !== null && isUntilReached(initial)) {
|
|
1828
1869
|
if (opts.json) opts.log(JSON.stringify(initial));
|
|
1829
|
-
else opts.log(
|
|
1870
|
+
else opts.log(import_chalk8.default.dim(`
|
|
1830
1871
|
[--wait] Phase '${opts.until}' already reached \u2014 exiting without polling.`));
|
|
1831
1872
|
return { timedOut: false, last: initial };
|
|
1832
1873
|
}
|
|
@@ -1837,13 +1878,13 @@ async function runWaitLoop(opts) {
|
|
|
1837
1878
|
else {
|
|
1838
1879
|
if (opts.until !== void 0) {
|
|
1839
1880
|
opts.log(
|
|
1840
|
-
|
|
1881
|
+
import_chalk8.default.yellow(
|
|
1841
1882
|
`
|
|
1842
1883
|
[--wait] Terminal state (${initial.relationshipState}, cycleComplete=${initial.cycleComplete}) reached before phase '${opts.until}' \u2014 exiting; phase unreachable.`
|
|
1843
1884
|
)
|
|
1844
1885
|
);
|
|
1845
1886
|
} else {
|
|
1846
|
-
opts.log(
|
|
1887
|
+
opts.log(import_chalk8.default.dim(`
|
|
1847
1888
|
[--wait] Already terminal \u2014 exiting.`));
|
|
1848
1889
|
}
|
|
1849
1890
|
}
|
|
@@ -1851,15 +1892,15 @@ async function runWaitLoop(opts) {
|
|
|
1851
1892
|
}
|
|
1852
1893
|
if (opts.until === void 0 && isActionable(initial)) {
|
|
1853
1894
|
if (opts.json) opts.log(JSON.stringify(initial));
|
|
1854
|
-
else opts.log(
|
|
1895
|
+
else opts.log(import_chalk8.default.dim(`
|
|
1855
1896
|
[--wait] Your turn already (nextActionOwner=${initial.nextActionOwner}) \u2014 exiting without polling.`));
|
|
1856
1897
|
return { timedOut: false, last: initial };
|
|
1857
1898
|
}
|
|
1858
1899
|
if (!opts.json) {
|
|
1859
1900
|
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})`;
|
|
1860
|
-
opts.log(
|
|
1901
|
+
opts.log(import_chalk8.default.dim(`
|
|
1861
1902
|
[--wait] ${blockerLabel}. Polling every ${opts.waitIntervalSec}s, timeout ${opts.waitTimeoutSec}s.`));
|
|
1862
|
-
opts.log(
|
|
1903
|
+
opts.log(import_chalk8.default.dim(`[--wait] Initial hint: ${initial.nextActionHint}`));
|
|
1863
1904
|
}
|
|
1864
1905
|
const startedAt = localNow();
|
|
1865
1906
|
const deadline = startedAt + opts.waitTimeoutSec * 1e3;
|
|
@@ -1879,7 +1920,7 @@ async function runWaitLoop(opts) {
|
|
|
1879
1920
|
} else {
|
|
1880
1921
|
target = `nextActionOwner=${next.nextActionOwner}`;
|
|
1881
1922
|
}
|
|
1882
|
-
opts.log(
|
|
1923
|
+
opts.log(import_chalk8.default.dim(`[--wait tick ${tickIndex}/${maxTicks}] state=${next.relationshipState}, ${formatPhaseSnapshot(next)} (${target})`));
|
|
1883
1924
|
}
|
|
1884
1925
|
if (exitPredicate(next)) {
|
|
1885
1926
|
const phaseReached = isUntilReached !== null ? isUntilReached(next) : false;
|
|
@@ -1889,16 +1930,16 @@ async function runWaitLoop(opts) {
|
|
|
1889
1930
|
opts.log("");
|
|
1890
1931
|
if (opts.until !== void 0) {
|
|
1891
1932
|
if (phaseReached) {
|
|
1892
|
-
opts.log(
|
|
1933
|
+
opts.log(import_chalk8.default.green(`[--wait] Phase '${opts.until}' reached.`));
|
|
1893
1934
|
} else {
|
|
1894
1935
|
opts.log(
|
|
1895
|
-
|
|
1936
|
+
import_chalk8.default.yellow(
|
|
1896
1937
|
`[--wait] Terminal state (${next.relationshipState}, cycleComplete=${next.cycleComplete}) reached before phase '${opts.until}' \u2014 phase unreachable.`
|
|
1897
1938
|
)
|
|
1898
1939
|
);
|
|
1899
1940
|
}
|
|
1900
1941
|
} else {
|
|
1901
|
-
opts.log(
|
|
1942
|
+
opts.log(import_chalk8.default.green(`[--wait] ${isTerminal(next) ? "Cycle terminated" : `Your turn (owner=${next.nextActionOwner})`}.`));
|
|
1902
1943
|
}
|
|
1903
1944
|
opts.log(formatStatusReport(next));
|
|
1904
1945
|
}
|
|
@@ -1911,14 +1952,14 @@ async function runWaitLoop(opts) {
|
|
|
1911
1952
|
} else {
|
|
1912
1953
|
if (opts.until !== void 0) {
|
|
1913
1954
|
opts.log(
|
|
1914
|
-
|
|
1955
|
+
import_chalk8.default.yellow(
|
|
1915
1956
|
`
|
|
1916
1957
|
[--wait] Timed out after ${opts.waitTimeoutSec}s without reaching phase '${opts.until}' (latest state: ${last.relationshipState}, hint: ${last.nextActionHint}).`
|
|
1917
1958
|
)
|
|
1918
1959
|
);
|
|
1919
1960
|
} else {
|
|
1920
1961
|
opts.log(
|
|
1921
|
-
|
|
1962
|
+
import_chalk8.default.yellow(`
|
|
1922
1963
|
[--wait] Timed out after ${opts.waitTimeoutSec}s without an actionable or terminal transition (your turn never came, cycle still in flight).`)
|
|
1923
1964
|
);
|
|
1924
1965
|
}
|
|
@@ -1946,41 +1987,41 @@ function parseUntilPhase(raw) {
|
|
|
1946
1987
|
function isPhaseTerminallyUnreachable(phase, s) {
|
|
1947
1988
|
if (untilPhaseMatched(phase, s)) return false;
|
|
1948
1989
|
if (s.relationshipState === "not_found") return true;
|
|
1949
|
-
if (s.relationshipState ===
|
|
1990
|
+
if (s.relationshipState === import_sdk8.RelationshipStates.CLOSED && phase !== "relationship.closed") return true;
|
|
1950
1991
|
return false;
|
|
1951
1992
|
}
|
|
1952
1993
|
function untilPhaseMatched(phase, s) {
|
|
1953
1994
|
switch (phase) {
|
|
1954
1995
|
case "delegation.offered":
|
|
1955
|
-
return s.latestDelegation?.state ===
|
|
1996
|
+
return s.latestDelegation?.state === import_sdk8.DelegationStates.OFFERED;
|
|
1956
1997
|
case "delegation.accepted":
|
|
1957
|
-
return s.latestDelegation?.state ===
|
|
1998
|
+
return s.latestDelegation?.state === import_sdk8.DelegationStates.ACCEPTED;
|
|
1958
1999
|
case "delegation.locked":
|
|
1959
|
-
return s.latestDelegation?.state ===
|
|
2000
|
+
return s.latestDelegation?.state === import_sdk8.DelegationStates.LOCKED;
|
|
1960
2001
|
case "delegation.disputing":
|
|
1961
|
-
return s.latestDelegation?.state ===
|
|
2002
|
+
return s.latestDelegation?.state === import_sdk8.DelegationStates.DISPUTING;
|
|
1962
2003
|
case "delegation.canceled":
|
|
1963
|
-
return s.latestDelegation?.state ===
|
|
2004
|
+
return s.latestDelegation?.state === import_sdk8.DelegationStates.CANCELED;
|
|
1964
2005
|
case "delegation.declined":
|
|
1965
|
-
return s.latestDelegation?.state ===
|
|
2006
|
+
return s.latestDelegation?.state === import_sdk8.DelegationStates.DECLINED;
|
|
1966
2007
|
case "work.requested":
|
|
1967
|
-
return s.latestWorkLog?.state ===
|
|
2008
|
+
return s.latestWorkLog?.state === import_sdk8.WorkLogStates.REQUESTED;
|
|
1968
2009
|
case "work.responded":
|
|
1969
|
-
return s.latestWorkLog?.state ===
|
|
2010
|
+
return s.latestWorkLog?.state === import_sdk8.WorkLogStates.RESPONDED;
|
|
1970
2011
|
case "receipt.proposed":
|
|
1971
2012
|
return s.latestReceipt != null;
|
|
1972
2013
|
case "relationship.pending":
|
|
1973
|
-
return s.relationshipState ===
|
|
2014
|
+
return s.relationshipState === import_sdk8.RelationshipStates.PENDING;
|
|
1974
2015
|
case "relationship.active":
|
|
1975
|
-
return s.relationshipState ===
|
|
2016
|
+
return s.relationshipState === import_sdk8.RelationshipStates.ACTIVE;
|
|
1976
2017
|
case "relationship.paused":
|
|
1977
|
-
return s.relationshipState ===
|
|
2018
|
+
return s.relationshipState === import_sdk8.RelationshipStates.PAUSED;
|
|
1978
2019
|
case "relationship.closed":
|
|
1979
|
-
return s.relationshipState ===
|
|
2020
|
+
return s.relationshipState === import_sdk8.RelationshipStates.CLOSED;
|
|
1980
2021
|
case "cycle.complete":
|
|
1981
2022
|
return s.cycleComplete;
|
|
1982
2023
|
case "cycle.released":
|
|
1983
|
-
return s.latestDelegation?.state ===
|
|
2024
|
+
return s.latestDelegation?.state === import_sdk8.DelegationStates.COMPLETED;
|
|
1984
2025
|
}
|
|
1985
2026
|
}
|
|
1986
2027
|
function parseWaitInterval(raw) {
|
|
@@ -2031,7 +2072,7 @@ async function composeStatus(api, signerDid, relationshipId, signer) {
|
|
|
2031
2072
|
const relationship = relationships.find((r) => r.relationshipId === relationshipId);
|
|
2032
2073
|
const counterpartyDid = relationship ? relationship.pairDidA === signerDid ? relationship.pairDidB : relationship.pairDidA : inferCounterpartyFromEntities(signerDid, allDelegations);
|
|
2033
2074
|
const delegations = allDelegations;
|
|
2034
|
-
const latestDelegation = pickLatestLive(delegations, [...
|
|
2075
|
+
const latestDelegation = pickLatestLive(delegations, [...import_sdk8.DELEGATION_ACTIVE_STATES]);
|
|
2035
2076
|
const [workLogs, receipts] = await Promise.all([
|
|
2036
2077
|
latestDelegation ? fetchAllPages(
|
|
2037
2078
|
(after) => api.listWorkLogs(relationshipId, signer, { limit: 100, delegationId: latestDelegation.delegationId, ...after ? { after } : {} })
|
|
@@ -2095,8 +2136,8 @@ function findReceiptForWorkLog(receipts, workLog, allWorkLogs = [workLog]) {
|
|
|
2095
2136
|
};
|
|
2096
2137
|
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;
|
|
2097
2138
|
if (!responseBody) return null;
|
|
2098
|
-
const expectedRequestHash = (0,
|
|
2099
|
-
const expectedResponseHash = (0,
|
|
2139
|
+
const expectedRequestHash = (0, import_sdk8.canonicalSha256Hex)(requestBody);
|
|
2140
|
+
const expectedResponseHash = (0, import_sdk8.canonicalSha256Hex)(responseBody);
|
|
2100
2141
|
const matches = receipts.filter((r) => r.requestHash === expectedRequestHash && r.responseHash === expectedResponseHash);
|
|
2101
2142
|
if (matches.length > 0) return pickLatest(matches);
|
|
2102
2143
|
const respondedSiblings = allWorkLogs.filter((wl) => wl.delegationId === workLog.delegationId && (wl.responseOutput !== void 0 || wl.responseError !== void 0)).length;
|
|
@@ -2138,49 +2179,49 @@ function nextAction(input) {
|
|
|
2138
2179
|
complete: false
|
|
2139
2180
|
};
|
|
2140
2181
|
}
|
|
2141
|
-
if (relationship.state ===
|
|
2182
|
+
if (relationship.state === import_sdk8.RelationshipStates.PENDING) {
|
|
2142
2183
|
return {
|
|
2143
2184
|
hint: "Relationship is PENDING \u2014 one side owes `heyarp send-handshake-response <peer> --decision accept | decline`",
|
|
2144
2185
|
owner: "either",
|
|
2145
2186
|
complete: false
|
|
2146
2187
|
};
|
|
2147
2188
|
}
|
|
2148
|
-
if (relationship.state ===
|
|
2189
|
+
if (relationship.state === import_sdk8.RelationshipStates.PAUSED) {
|
|
2149
2190
|
return { hint: "Relationship is PAUSED \u2014 owner must `heyarp unpause` before any envelopes flow", owner: "either", complete: false };
|
|
2150
2191
|
}
|
|
2151
|
-
if (relationship.state ===
|
|
2192
|
+
if (relationship.state === import_sdk8.RelationshipStates.CLOSED) {
|
|
2152
2193
|
return { hint: "Relationship is CLOSED \u2014 terminal state, no further action possible. Start a fresh handshake to reopen.", owner: "none", complete: false };
|
|
2153
2194
|
}
|
|
2154
|
-
if (!latestDelegation || latestDelegation.state ===
|
|
2195
|
+
if (!latestDelegation || latestDelegation.state === import_sdk8.DelegationStates.DECLINED || latestDelegation.state === import_sdk8.DelegationStates.CANCELED) {
|
|
2155
2196
|
return {
|
|
2156
2197
|
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>`",
|
|
2157
2198
|
owner: "either",
|
|
2158
2199
|
complete: false
|
|
2159
2200
|
};
|
|
2160
2201
|
}
|
|
2161
|
-
if (latestDelegation.state ===
|
|
2202
|
+
if (latestDelegation.state === import_sdk8.DelegationStates.DISPUTING) {
|
|
2162
2203
|
return {
|
|
2163
2204
|
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.`,
|
|
2164
2205
|
owner: "none",
|
|
2165
2206
|
complete: false
|
|
2166
2207
|
};
|
|
2167
2208
|
}
|
|
2168
|
-
if (latestDelegation.state ===
|
|
2209
|
+
if (latestDelegation.state === import_sdk8.DelegationStates.COMPLETED) {
|
|
2169
2210
|
return {
|
|
2170
2211
|
hint: "Cycle COMPLETE \u2014 payment claimed on chain (lock paid; the receipt carries releaseStatus=paid)",
|
|
2171
2212
|
owner: "none",
|
|
2172
2213
|
complete: true
|
|
2173
2214
|
};
|
|
2174
2215
|
}
|
|
2175
|
-
if (latestDelegation.state ===
|
|
2216
|
+
if (latestDelegation.state === import_sdk8.DelegationStates.FAILED || latestDelegation.state === import_sdk8.DelegationStates.REFUNDED || latestDelegation.state === import_sdk8.DelegationStates.DISPUTE_RESOLVED) {
|
|
2176
2217
|
const stateLabel = latestDelegation.state.toUpperCase();
|
|
2177
|
-
const reason = latestDelegation.state ===
|
|
2218
|
+
const reason = latestDelegation.state === import_sdk8.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_sdk8.DelegationStates.REFUNDED ? (
|
|
2178
2219
|
// Keyed on the DELEGATION row's releaseStatus, not the
|
|
2179
2220
|
// receipt's: in the claim-expired path the worker never
|
|
2180
2221
|
// submitted anything, so no receipt row exists to carry
|
|
2181
2222
|
// the outcome — the delegation copy is always present
|
|
2182
2223
|
// on indexer-driven terminals.
|
|
2183
|
-
latestDelegation.releaseStatus ===
|
|
2224
|
+
latestDelegation.releaseStatus === import_sdk8.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_sdk8.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"
|
|
2184
2225
|
) : "admin closed the delegation via the dispute-resolution path";
|
|
2185
2226
|
return {
|
|
2186
2227
|
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).`,
|
|
@@ -2188,7 +2229,7 @@ function nextAction(input) {
|
|
|
2188
2229
|
complete: false
|
|
2189
2230
|
};
|
|
2190
2231
|
}
|
|
2191
|
-
if (latestDelegation.state ===
|
|
2232
|
+
if (latestDelegation.state === import_sdk8.DelegationStates.OFFERED) {
|
|
2192
2233
|
const iAmOfferer = latestDelegation.offererDid === signerDid;
|
|
2193
2234
|
const stateLabel = "OFFERED";
|
|
2194
2235
|
return {
|
|
@@ -2197,7 +2238,7 @@ function nextAction(input) {
|
|
|
2197
2238
|
complete: false
|
|
2198
2239
|
};
|
|
2199
2240
|
}
|
|
2200
|
-
if (latestDelegation.state ===
|
|
2241
|
+
if (latestDelegation.state === import_sdk8.DelegationStates.ACCEPTED && !latestWorkLog) {
|
|
2201
2242
|
const iAmOfferer = latestDelegation.offererDid === signerDid;
|
|
2202
2243
|
return {
|
|
2203
2244
|
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`,
|
|
@@ -2205,7 +2246,7 @@ function nextAction(input) {
|
|
|
2205
2246
|
complete: false
|
|
2206
2247
|
};
|
|
2207
2248
|
}
|
|
2208
|
-
if (latestDelegation.state ===
|
|
2249
|
+
if (latestDelegation.state === import_sdk8.DelegationStates.PENDING_LOCK_FINALIZATION && !latestWorkLog) {
|
|
2209
2250
|
return {
|
|
2210
2251
|
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\`.`,
|
|
2211
2252
|
owner: "none",
|
|
@@ -2220,7 +2261,7 @@ function nextAction(input) {
|
|
|
2220
2261
|
complete: false
|
|
2221
2262
|
};
|
|
2222
2263
|
}
|
|
2223
|
-
if (latestWorkLog.state ===
|
|
2264
|
+
if (latestWorkLog.state === import_sdk8.WorkLogStates.REQUESTED) {
|
|
2224
2265
|
const iAmPayee = latestWorkLog.payeeDid === signerDid;
|
|
2225
2266
|
return {
|
|
2226
2267
|
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\``,
|
|
@@ -2272,106 +2313,106 @@ function formatStatusReport(s) {
|
|
|
2272
2313
|
const lines = [];
|
|
2273
2314
|
lines.push(cycleHeadline(s));
|
|
2274
2315
|
lines.push("");
|
|
2275
|
-
lines.push(
|
|
2316
|
+
lines.push(import_chalk8.default.bold("Relationship"));
|
|
2276
2317
|
lines.push(` state: ${stateColor(s.relationshipState)}`);
|
|
2277
|
-
if (s.counterpartyDid) lines.push(` counterparty: ${
|
|
2318
|
+
if (s.counterpartyDid) lines.push(` counterparty: ${import_chalk8.default.cyan(s.counterpartyDid)}`);
|
|
2278
2319
|
lines.push("");
|
|
2279
|
-
lines.push(
|
|
2320
|
+
lines.push(import_chalk8.default.bold("Latest delegation"));
|
|
2280
2321
|
if (s.latestDelegation) {
|
|
2281
2322
|
lines.push(` ${s.latestDelegation.delegationId} state=${stateColor(s.latestDelegation.state)}`);
|
|
2282
|
-
lines.push(` offerer: ${
|
|
2323
|
+
lines.push(` offerer: ${import_chalk8.default.cyan(s.latestDelegation.offererDid)}`);
|
|
2283
2324
|
if (s.latestDelegation.title) lines.push(` title: ${s.latestDelegation.title}`);
|
|
2284
2325
|
if (s.latestDelegation.scopeSummary) lines.push(` scope: ${s.latestDelegation.scopeSummary}`);
|
|
2285
2326
|
} else {
|
|
2286
|
-
lines.push(
|
|
2327
|
+
lines.push(import_chalk8.default.dim(" (none)"));
|
|
2287
2328
|
}
|
|
2288
2329
|
lines.push("");
|
|
2289
|
-
lines.push(
|
|
2330
|
+
lines.push(import_chalk8.default.bold("Latest work_log"));
|
|
2290
2331
|
if (s.latestWorkLog) {
|
|
2291
2332
|
lines.push(` request_id=${s.latestWorkLog.requestId} state=${stateColor(s.latestWorkLog.state)}`);
|
|
2292
2333
|
} else {
|
|
2293
|
-
lines.push(
|
|
2334
|
+
lines.push(import_chalk8.default.dim(" (none)"));
|
|
2294
2335
|
}
|
|
2295
2336
|
lines.push("");
|
|
2296
|
-
lines.push(
|
|
2337
|
+
lines.push(import_chalk8.default.bold("Latest receipt"));
|
|
2297
2338
|
if (s.latestReceipt) {
|
|
2298
2339
|
lines.push(` ${stateColor("proposed")} verdict=${s.latestReceipt.verdictProposed}`);
|
|
2299
2340
|
} else {
|
|
2300
|
-
lines.push(
|
|
2341
|
+
lines.push(import_chalk8.default.dim(" (none)"));
|
|
2301
2342
|
}
|
|
2302
2343
|
lines.push("");
|
|
2303
|
-
lines.push(
|
|
2304
|
-
const ownerLabel = s.nextActionOwner === "me" ?
|
|
2344
|
+
lines.push(import_chalk8.default.bold("Next action"));
|
|
2345
|
+
const ownerLabel = s.nextActionOwner === "me" ? import_chalk8.default.green("me") : s.nextActionOwner === "counterparty" ? import_chalk8.default.yellow("counterparty") : s.nextActionOwner === "either" ? import_chalk8.default.cyan("either side") : import_chalk8.default.dim("\u2014");
|
|
2305
2346
|
lines.push(` whose turn: ${ownerLabel}`);
|
|
2306
2347
|
lines.push(` hint: ${s.nextActionHint}`);
|
|
2307
|
-
if (s.cycleComplete) lines.push(` ${
|
|
2348
|
+
if (s.cycleComplete) lines.push(` ${import_chalk8.default.green("\u2713 Cycle complete.")}`);
|
|
2308
2349
|
return lines.join("\n");
|
|
2309
2350
|
}
|
|
2310
2351
|
function cycleHeadline(s) {
|
|
2311
2352
|
if (s.cycleComplete) {
|
|
2312
|
-
return `${
|
|
2353
|
+
return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.green.bold("COMPLETE")} ${import_chalk8.default.dim("\u2014 payment proven on chain")}`;
|
|
2313
2354
|
}
|
|
2314
2355
|
switch (s.relationshipState) {
|
|
2315
2356
|
case "not_found":
|
|
2316
|
-
return `${
|
|
2357
|
+
return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.red.bold("NOT FOUND")} ${import_chalk8.default.dim("\u2014 relationship missing or signer is not a member")}`;
|
|
2317
2358
|
case "unknown":
|
|
2318
|
-
return `${
|
|
2319
|
-
case
|
|
2320
|
-
return `${
|
|
2321
|
-
case
|
|
2322
|
-
return `${
|
|
2323
|
-
case
|
|
2324
|
-
return `${
|
|
2325
|
-
case
|
|
2359
|
+
return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.yellow.bold("UNKNOWN")} ${import_chalk8.default.dim("\u2014 state probe inconclusive; hint below is advisory")}`;
|
|
2360
|
+
case import_sdk8.RelationshipStates.CLOSED:
|
|
2361
|
+
return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.red.bold("CLOSED")} ${import_chalk8.default.dim("\u2014 relationship terminal, no further protocol action")}`;
|
|
2362
|
+
case import_sdk8.RelationshipStates.PAUSED:
|
|
2363
|
+
return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.yellow.bold("PAUSED")} ${import_chalk8.default.dim("\u2014 relationship soft-disabled, resume to continue")}`;
|
|
2364
|
+
case import_sdk8.RelationshipStates.PENDING:
|
|
2365
|
+
return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.yellow.bold("PENDING")} ${import_chalk8.default.dim("\u2014 awaiting handshake_response")}`;
|
|
2366
|
+
case import_sdk8.RelationshipStates.ACTIVE:
|
|
2326
2367
|
default:
|
|
2327
|
-
return `${
|
|
2368
|
+
return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.cyan.bold("ACTIVE")} ${import_chalk8.default.dim('\u2014 work in progress; see "Next action" below')}`;
|
|
2328
2369
|
}
|
|
2329
2370
|
}
|
|
2330
2371
|
function stateColor(state) {
|
|
2331
|
-
const c = state === "active" || state === "accepted" || state === "locked" || state === "responded" || state === "completed" ?
|
|
2372
|
+
const c = state === "active" || state === "accepted" || state === "locked" || state === "responded" || state === "completed" ? import_chalk8.default.green : state === "pending" || state === "requested" || state === "offered" || state === "pending_lock_finalization" ? import_chalk8.default.yellow : state === "closed" || state === "declined" || state === "canceled" || state === "replaced" || state === "not_found" || // Terminal failure states deserve the same red
|
|
2332
2373
|
// treatment as declined/canceled so an operator
|
|
2333
2374
|
// scanning `heyarp status` immediately sees
|
|
2334
2375
|
// "this is dead, don't follow the hint blindly".
|
|
2335
|
-
state === "failed" || state === "refunded" || state === "dispute_resolved" ?
|
|
2376
|
+
state === "failed" || state === "refunded" || state === "dispute_resolved" ? import_chalk8.default.red : import_chalk8.default.cyan;
|
|
2336
2377
|
return c(state);
|
|
2337
2378
|
}
|
|
2338
2379
|
|
|
2339
2380
|
// src/commands/wallet.ts
|
|
2340
|
-
var
|
|
2381
|
+
var import_sdk11 = require("@heyanon-arp/sdk");
|
|
2341
2382
|
var import_utils = require("@noble/hashes/utils");
|
|
2342
2383
|
var import_web32 = require("@solana/web3.js");
|
|
2343
2384
|
init_api();
|
|
2344
2385
|
init_config();
|
|
2345
2386
|
|
|
2346
2387
|
// src/solana/escrow-ix.ts
|
|
2347
|
-
var
|
|
2388
|
+
var import_sdk9 = require("@heyanon-arp/sdk");
|
|
2348
2389
|
var import_web3 = require("@solana/web3.js");
|
|
2349
|
-
var SPL_TOKEN_PROGRAM_ID = new import_web3.PublicKey(
|
|
2350
|
-
var ASSOCIATED_TOKEN_PROGRAM_ID = new import_web3.PublicKey(
|
|
2351
|
-
var NATIVE_SOL_MINT = new import_web3.PublicKey(
|
|
2390
|
+
var SPL_TOKEN_PROGRAM_ID = new import_web3.PublicKey(import_sdk9.SPL_TOKEN_PROGRAM_ID_BASE58);
|
|
2391
|
+
var ASSOCIATED_TOKEN_PROGRAM_ID = new import_web3.PublicKey(import_sdk9.ASSOCIATED_TOKEN_PROGRAM_ID_BASE58);
|
|
2392
|
+
var NATIVE_SOL_MINT = new import_web3.PublicKey(import_sdk9.NATIVE_SOL_MINT_BASE58);
|
|
2352
2393
|
function deriveLockPda(programId, lockId) {
|
|
2353
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2394
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.LOCK), Buffer.from(lockId)], programId)[0];
|
|
2354
2395
|
}
|
|
2355
2396
|
function deriveEscrowPda(programId, lockId) {
|
|
2356
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2397
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.ESCROW), Buffer.from(lockId)], programId)[0];
|
|
2357
2398
|
}
|
|
2358
2399
|
function deriveConfigPda(programId) {
|
|
2359
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2400
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.CONFIG)], programId)[0];
|
|
2360
2401
|
}
|
|
2361
2402
|
function deriveStakeVaultPda(programId) {
|
|
2362
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2403
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.STAKE_VAULT)], programId)[0];
|
|
2363
2404
|
}
|
|
2364
2405
|
function deriveCollateralConfigPda(programId, mint) {
|
|
2365
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2406
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.COLLATERAL), mint.toBuffer()], programId)[0];
|
|
2366
2407
|
}
|
|
2367
2408
|
function deriveDisputeResolutionPda(programId, lockId) {
|
|
2368
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2409
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.DISPUTE_RESOLUTION), Buffer.from(lockId)], programId)[0];
|
|
2369
2410
|
}
|
|
2370
2411
|
function deriveOperatorAuthPda(programId, operator) {
|
|
2371
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2412
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.OPERATOR_AUTH), operator.toBuffer()], programId)[0];
|
|
2372
2413
|
}
|
|
2373
2414
|
function deriveEventAuthorityPda(programId) {
|
|
2374
|
-
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(
|
|
2415
|
+
return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk9.ESCROW_PDA_SEEDS.EVENT_AUTHORITY)], programId)[0];
|
|
2375
2416
|
}
|
|
2376
2417
|
function deriveAta(owner, mint) {
|
|
2377
2418
|
return import_web3.PublicKey.findProgramAddressSync([owner.toBuffer(), SPL_TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
|
|
@@ -2386,12 +2427,12 @@ function meta(pubkey, opts = {}) {
|
|
|
2386
2427
|
return { pubkey, isSigner: opts.signer === true, isWritable: opts.writable === true };
|
|
2387
2428
|
}
|
|
2388
2429
|
function noArgIx(programId, name, keys) {
|
|
2389
|
-
return new import_web3.TransactionInstruction({ programId, keys, data: Buffer.from((0,
|
|
2430
|
+
return new import_web3.TransactionInstruction({ programId, keys, data: Buffer.from((0, import_sdk9.buildLifecycleIxData)(name)) });
|
|
2390
2431
|
}
|
|
2391
2432
|
function buildCreateLockIx(input) {
|
|
2392
2433
|
const { programId, lockId } = input;
|
|
2393
2434
|
const native = input.mint === null;
|
|
2394
|
-
const data = Buffer.from((0,
|
|
2435
|
+
const data = Buffer.from((0, import_sdk9.buildCreateLockIxData)({ lockId, amount: input.amount, conditionHash: input.conditionHash }, { native }));
|
|
2395
2436
|
const head = [
|
|
2396
2437
|
meta(input.payer, { signer: true, writable: true }),
|
|
2397
2438
|
meta(input.payee),
|
|
@@ -2527,7 +2568,7 @@ function buildOpenDisputeIx(input) {
|
|
|
2527
2568
|
function buildResolveDisputeIx(input) {
|
|
2528
2569
|
const { programId, lockId } = input;
|
|
2529
2570
|
const native = input.mint === null;
|
|
2530
|
-
const data = Buffer.from((0,
|
|
2571
|
+
const data = Buffer.from((0, import_sdk9.buildResolveDisputeIxData)(input.args, { native }));
|
|
2531
2572
|
if (native) {
|
|
2532
2573
|
return new import_web3.TransactionInstruction({
|
|
2533
2574
|
programId,
|
|
@@ -2604,17 +2645,17 @@ function buildCloseDisputeIx(input) {
|
|
|
2604
2645
|
]);
|
|
2605
2646
|
}
|
|
2606
2647
|
async function fetchLockAccount(conn, programId, delegationId) {
|
|
2607
|
-
const lockId = (0,
|
|
2648
|
+
const lockId = (0, import_sdk9.deriveLockId)(delegationId);
|
|
2608
2649
|
const lockPda = deriveLockPda(programId, lockId);
|
|
2609
2650
|
const info = await conn.getAccountInfo(lockPda);
|
|
2610
2651
|
if (!info) return null;
|
|
2611
|
-
return { lockId, lockPda, lock: (0,
|
|
2652
|
+
return { lockId, lockPda, lock: (0, import_sdk9.decodeLockAccount)(Uint8Array.from(info.data)) };
|
|
2612
2653
|
}
|
|
2613
2654
|
|
|
2614
2655
|
// src/commands/token-amount.ts
|
|
2615
|
-
var
|
|
2656
|
+
var import_sdk10 = require("@heyanon-arp/sdk");
|
|
2616
2657
|
function toBaseUnits(amountDecimal, decimals) {
|
|
2617
|
-
if (!(0,
|
|
2658
|
+
if (!(0, import_sdk10.isDecimalAmountString)(amountDecimal)) {
|
|
2618
2659
|
throw new Error(`amount '${amountDecimal}' is not a non-negative decimal number`);
|
|
2619
2660
|
}
|
|
2620
2661
|
if (!Number.isInteger(decimals) || decimals < 0 || decimals > 255) {
|
|
@@ -2643,8 +2684,8 @@ function normaliseDelegationId(raw) {
|
|
|
2643
2684
|
}
|
|
2644
2685
|
throw new Error(`wallet: --delegation-id must be either 'del_<uuid>' or a bare canonical-lowercase UUID (got '${raw}')`);
|
|
2645
2686
|
}
|
|
2646
|
-
var SPL_TOKEN_PROGRAM_ID2 = new import_web32.PublicKey(
|
|
2647
|
-
var ASSOCIATED_TOKEN_PROGRAM_ID2 = new import_web32.PublicKey(
|
|
2687
|
+
var SPL_TOKEN_PROGRAM_ID2 = new import_web32.PublicKey(import_sdk11.SPL_TOKEN_PROGRAM_ID_BASE58);
|
|
2688
|
+
var ASSOCIATED_TOKEN_PROGRAM_ID2 = new import_web32.PublicKey(import_sdk11.ASSOCIATED_TOKEN_PROGRAM_ID_BASE58);
|
|
2648
2689
|
var FALLBACK_RPC_URL = "https://api.mainnet-beta.solana.com";
|
|
2649
2690
|
function resolveRpcUrl(opts) {
|
|
2650
2691
|
if (opts.rpcUrl !== void 0 && opts.rpcUrl !== "") return opts.rpcUrl;
|
|
@@ -2664,7 +2705,7 @@ function redactRpcUrl(url) {
|
|
|
2664
2705
|
return "<redacted>";
|
|
2665
2706
|
}
|
|
2666
2707
|
}
|
|
2667
|
-
var FALLBACK_PROGRAM_ID =
|
|
2708
|
+
var FALLBACK_PROGRAM_ID = import_sdk11.ESCROW_PROGRAM_ID_BASE58;
|
|
2668
2709
|
async function resolveProgramIdWithSource(api, opts) {
|
|
2669
2710
|
if (opts.programId !== void 0 && opts.programId !== "") {
|
|
2670
2711
|
return { programId: opts.programId, source: "flag" };
|
|
@@ -2748,7 +2789,7 @@ async function derivePdasHandler(opts) {
|
|
|
2748
2789
|
const normalisedDelegationId = normaliseDelegationId(opts.delegationId);
|
|
2749
2790
|
const api = new ArpApiClient(opts.server);
|
|
2750
2791
|
const programId = new import_web32.PublicKey(await resolveProgramIdStrict(api, opts, "wallet derive-pdas"));
|
|
2751
|
-
const lockIdBytes = (0,
|
|
2792
|
+
const lockIdBytes = (0, import_sdk11.deriveLockId)(normalisedDelegationId);
|
|
2752
2793
|
const lockIdSeed = Buffer.from(lockIdBytes);
|
|
2753
2794
|
const lockIdHex = Buffer.from(lockIdBytes).toString("hex");
|
|
2754
2795
|
const [lockPda] = import_web32.PublicKey.findProgramAddressSync([Buffer.from("lock"), lockIdSeed], programId);
|
|
@@ -2767,11 +2808,11 @@ async function derivePdasHandler(opts) {
|
|
|
2767
2808
|
};
|
|
2768
2809
|
}
|
|
2769
2810
|
var TERMINAL_METHOD = {
|
|
2770
|
-
[
|
|
2771
|
-
[
|
|
2772
|
-
[
|
|
2773
|
-
[
|
|
2774
|
-
[
|
|
2811
|
+
[import_sdk11.LockStates.PAID]: "claim_work_payment",
|
|
2812
|
+
[import_sdk11.LockStates.CANCELED]: "cancel_lock",
|
|
2813
|
+
[import_sdk11.LockStates.REVOKED]: "claim_expired_work",
|
|
2814
|
+
[import_sdk11.LockStates.DISPUTE_RESOLVED]: "resolve_dispute",
|
|
2815
|
+
[import_sdk11.LockStates.DISPUTE_CLOSED]: "close_dispute"
|
|
2775
2816
|
};
|
|
2776
2817
|
function registerVerifyRelease(cmd) {
|
|
2777
2818
|
cmd.command("verify-release").description(
|
|
@@ -2817,7 +2858,7 @@ async function verifyReleaseHandler(opts) {
|
|
|
2817
2858
|
const rpcUrl = resolveRpcUrlStrict(opts);
|
|
2818
2859
|
const conn = new import_web32.Connection(rpcUrl, "confirmed");
|
|
2819
2860
|
const fetched = await fetchLockAccount(conn, programId, normalisedDelegationId);
|
|
2820
|
-
const lockId = (0,
|
|
2861
|
+
const lockId = (0, import_sdk11.deriveLockId)(normalisedDelegationId);
|
|
2821
2862
|
const lockPda = deriveLockPda(programId, lockId);
|
|
2822
2863
|
const escrowPda = deriveEscrowPda(programId, lockId);
|
|
2823
2864
|
if (!fetched) {
|
|
@@ -2838,7 +2879,7 @@ async function verifyReleaseHandler(opts) {
|
|
|
2838
2879
|
lock_pda: lockPda.toBase58(),
|
|
2839
2880
|
escrow_pda: escrowPda.toBase58(),
|
|
2840
2881
|
lock_account_exists: true,
|
|
2841
|
-
released: status ===
|
|
2882
|
+
released: status === import_sdk11.LockStates.PAID,
|
|
2842
2883
|
status,
|
|
2843
2884
|
...TERMINAL_METHOD[status] !== void 0 ? { release_method: TERMINAL_METHOD[status] } : {},
|
|
2844
2885
|
lock_state: lock.stateByte,
|
|
@@ -2848,23 +2889,23 @@ async function verifyReleaseHandler(opts) {
|
|
|
2848
2889
|
}
|
|
2849
2890
|
function renderStatusLine(status) {
|
|
2850
2891
|
switch (status) {
|
|
2851
|
-
case
|
|
2892
|
+
case import_sdk11.LockStates.PAID:
|
|
2852
2893
|
return "\u2713 paid \u2014 claim_work_payment landed (buyer approval or post-review self-claim); the payee was paid net of any protocol fee";
|
|
2853
|
-
case
|
|
2894
|
+
case import_sdk11.LockStates.CREATED:
|
|
2854
2895
|
return "\u2717 created \u2014 funded, awaiting the worker accept_lock (stake) \u2014 or a buyer cancel";
|
|
2855
|
-
case
|
|
2896
|
+
case import_sdk11.LockStates.IN_PROGRESS:
|
|
2856
2897
|
return "\u2717 in_progress \u2014 worker accepted + staked; work window running";
|
|
2857
|
-
case
|
|
2898
|
+
case import_sdk11.LockStates.SUBMITTED:
|
|
2858
2899
|
return "\u2717 submitted \u2014 work delivered on-chain; review window running (buyer claims to approve, disputes to refuse; worker self-claims after expiry)";
|
|
2859
|
-
case
|
|
2900
|
+
case import_sdk11.LockStates.DISPUTING:
|
|
2860
2901
|
return "\u2717 disputing \u2014 buyer disputed; operator has the dispute window to rule, after that either party can close";
|
|
2861
|
-
case
|
|
2902
|
+
case import_sdk11.LockStates.CANCELED:
|
|
2862
2903
|
return "\u2717 canceled \u2014 buyer canceled pre-accept; escrow returned";
|
|
2863
|
-
case
|
|
2904
|
+
case import_sdk11.LockStates.REVOKED:
|
|
2864
2905
|
return "\u2717 revoked \u2014 work window lapsed unsubmitted; buyer reclaimed the escrow + the worker stake";
|
|
2865
|
-
case
|
|
2906
|
+
case import_sdk11.LockStates.DISPUTE_RESOLVED:
|
|
2866
2907
|
return "\u2717 dispute_resolved \u2014 operator ruled; winner took the escrow per the on-chain split";
|
|
2867
|
-
case
|
|
2908
|
+
case import_sdk11.LockStates.DISPUTE_CLOSED:
|
|
2868
2909
|
return "\u2717 dispute_closed \u2014 dispute window lapsed unresolved; escrow returned to the buyer, stakes returned";
|
|
2869
2910
|
case "lock_never_created":
|
|
2870
2911
|
return "\u2717 lock_never_created \u2014 no Lock PDA on this cluster/program; create_lock never fired (or wrong --rpc-url/--program-id)";
|
|
@@ -3050,7 +3091,7 @@ async function createLockHandler(opts) {
|
|
|
3050
3091
|
if (clusterTag !== 0 && clusterTag !== 1) {
|
|
3051
3092
|
throw new Error(`--cluster-tag must be 0 (devnet) or 1 (mainnet) (got ${clusterTag})`);
|
|
3052
3093
|
}
|
|
3053
|
-
const clusterCaip2 = clusterTag === 1 ?
|
|
3094
|
+
const clusterCaip2 = clusterTag === 1 ? import_sdk11.SOLANA_CLUSTER_IDS["solana-mainnet"] : import_sdk11.SOLANA_CLUSTER_IDS["solana-devnet"];
|
|
3054
3095
|
const expectedLockAsset = typeof opts.mintPubkey === "string" && opts.mintPubkey !== "" ? { kind: "spl", mint: parsePubkey(opts.mintPubkey, "--mint-pubkey").toBase58(), cluster: clusterCaip2 } : { kind: "native" };
|
|
3055
3096
|
if (!offlineMode) {
|
|
3056
3097
|
await preflightLockCurrency(api, agent, normalisedDelegationId, expectedLockAsset);
|
|
@@ -3060,7 +3101,7 @@ async function createLockHandler(opts) {
|
|
|
3060
3101
|
const conn = new import_web32.Connection(rpcUrl, "confirmed");
|
|
3061
3102
|
const asset = await resolveCreateLockAsset(conn, opts, payerKp.publicKey, clusterCaip2);
|
|
3062
3103
|
const amount = asset.amount;
|
|
3063
|
-
const lockIdBytes = (0,
|
|
3104
|
+
const lockIdBytes = (0, import_sdk11.deriveLockId)(normalisedDelegationId);
|
|
3064
3105
|
const ix = buildCreateLockIx({
|
|
3065
3106
|
programId,
|
|
3066
3107
|
lockId: lockIdBytes,
|
|
@@ -3145,7 +3186,7 @@ function registerDelegationCommands(root) {
|
|
|
3145
3186
|
registerCancel(cmd);
|
|
3146
3187
|
}
|
|
3147
3188
|
function registerOffer(parent) {
|
|
3148
|
-
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
|
|
3189
|
+
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("--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_sdk12.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_sdk12.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(
|
|
3149
3190
|
"--json",
|
|
3150
3191
|
'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.',
|
|
3151
3192
|
false
|
|
@@ -3260,16 +3301,16 @@ async function runOffer(recipientDid, opts) {
|
|
|
3260
3301
|
"delegation offer: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds dumps that would break `--json | jq`."
|
|
3261
3302
|
);
|
|
3262
3303
|
}
|
|
3263
|
-
|
|
3304
|
+
recipientDid = await resolveRecipient(opts.server, "delegation offer", recipientDid, { json: opts.json });
|
|
3264
3305
|
const ttlSeconds = parseTtl("delegation offer", opts.ttl);
|
|
3265
3306
|
if (!opts.title || opts.title.length === 0) {
|
|
3266
3307
|
throw new Error("delegation offer: --title is required (server-side validator rejects empty offers)");
|
|
3267
3308
|
}
|
|
3268
3309
|
const terms = parseOfferTerms("delegation offer", opts);
|
|
3269
3310
|
const offeredAssetId = terms.currency?.asset_id;
|
|
3270
|
-
if (offeredAssetId && !(0,
|
|
3311
|
+
if (offeredAssetId && !(0, import_sdk12.isWhitelistedAssetId)(offeredAssetId)) {
|
|
3271
3312
|
console.error(
|
|
3272
|
-
|
|
3313
|
+
import_chalk9.default.yellow(
|
|
3273
3314
|
`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'.`
|
|
3274
3315
|
)
|
|
3275
3316
|
);
|
|
@@ -3288,43 +3329,43 @@ async function runOffer(recipientDid, opts) {
|
|
|
3288
3329
|
const api = new ArpApiClient(opts.server);
|
|
3289
3330
|
const sender = resolveSenderAgent("delegation offer", opts.server, opts.fromDid);
|
|
3290
3331
|
const content = {
|
|
3291
|
-
action:
|
|
3332
|
+
action: import_sdk12.DelegationActions.OFFER,
|
|
3292
3333
|
delegation_id: delegationId,
|
|
3293
3334
|
title: opts.title,
|
|
3294
3335
|
...terms
|
|
3295
3336
|
};
|
|
3296
3337
|
const body = { type: "delegation", content };
|
|
3297
|
-
progress(opts.json,
|
|
3298
|
-
progress(opts.json,
|
|
3299
|
-
progress(opts.json,
|
|
3300
|
-
progress(opts.json,
|
|
3338
|
+
progress(opts.json, import_chalk9.default.dim(`Server: ${api.serverUrl}`));
|
|
3339
|
+
progress(opts.json, import_chalk9.default.dim(`Sender: ${sender.did}`));
|
|
3340
|
+
progress(opts.json, import_chalk9.default.dim(`Recipient: ${recipientDid}`));
|
|
3341
|
+
progress(opts.json, import_chalk9.default.dim(`Delegation: ${delegationId}`));
|
|
3301
3342
|
let result;
|
|
3302
3343
|
try {
|
|
3303
3344
|
result = await sendDelegationEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
3304
3345
|
} catch (err) {
|
|
3305
|
-
if (err instanceof ApiError && err.payload.code ===
|
|
3346
|
+
if (err instanceof ApiError && err.payload.code === import_sdk12.DelegationOfferRejectionCodes.ASSET_NOT_ALLOWED) {
|
|
3306
3347
|
const d = err.payload.details;
|
|
3307
|
-
console.error(
|
|
3348
|
+
console.error(import_chalk9.default.yellow(`
|
|
3308
3349
|
The server's payment-asset whitelist rejected this currency.`));
|
|
3309
3350
|
if (d !== void 0) {
|
|
3310
|
-
console.error(
|
|
3311
|
-
console.error(
|
|
3351
|
+
console.error(import_chalk9.default.dim(` offered: ${JSON.stringify(d.offered)}`));
|
|
3352
|
+
console.error(import_chalk9.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
|
|
3312
3353
|
}
|
|
3313
|
-
console.error(
|
|
3354
|
+
console.error(import_chalk9.default.dim(`
|
|
3314
3355
|
See the whitelist (shorthand keys + canonical decimals):
|
|
3315
3356
|
heyarp assets
|
|
3316
3357
|
then re-offer with a whitelisted --currency.`));
|
|
3317
3358
|
}
|
|
3318
|
-
if (err instanceof ApiError && err.payload.code ===
|
|
3359
|
+
if (err instanceof ApiError && err.payload.code === import_sdk12.DelegationOfferRejectionCodes.PRICING_MISMATCH) {
|
|
3319
3360
|
const d = err.payload.details;
|
|
3320
|
-
console.error(
|
|
3361
|
+
console.error(import_chalk9.default.yellow(`
|
|
3321
3362
|
The recipient's published accept-prefs rejected this offer${d?.reason ? ` (mismatch: ${d.reason})` : ""}.`));
|
|
3322
3363
|
if (d !== void 0) {
|
|
3323
|
-
console.error(
|
|
3324
|
-
console.error(
|
|
3364
|
+
console.error(import_chalk9.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
|
|
3365
|
+
console.error(import_chalk9.default.dim(` offered: ${JSON.stringify(d.offered)}`));
|
|
3325
3366
|
}
|
|
3326
3367
|
console.error(
|
|
3327
|
-
|
|
3368
|
+
import_chalk9.default.dim(
|
|
3328
3369
|
`
|
|
3329
3370
|
Check what the recipient accepts BEFORE offering:
|
|
3330
3371
|
heyarp agents accept-prefs show ${recipientDid}
|
|
@@ -3332,12 +3373,12 @@ then re-run with matching --currency / --amount.`
|
|
|
3332
3373
|
)
|
|
3333
3374
|
);
|
|
3334
3375
|
}
|
|
3335
|
-
if (err instanceof ApiError && err.payload.code ===
|
|
3376
|
+
if (err instanceof ApiError && err.payload.code === import_sdk12.DelegationOfferRejectionCodes.CAPACITY_EXCEEDED) {
|
|
3336
3377
|
const d = err.payload.details;
|
|
3337
3378
|
const cap = d?.maxActive === 0 ? "closed for new offers (busy)" : `at capacity (${d?.currentActive}/${d?.maxActive} active delegations)`;
|
|
3338
|
-
console.error(
|
|
3379
|
+
console.error(import_chalk9.default.yellow(`
|
|
3339
3380
|
The recipient is ${cap}.`));
|
|
3340
|
-
console.error(
|
|
3381
|
+
console.error(import_chalk9.default.dim("\nThis is TRANSIENT \u2014 your terms are fine. Retry the same offer later, or pick another worker (`heyarp agents --tag \u2026`)."));
|
|
3341
3382
|
}
|
|
3342
3383
|
throw err;
|
|
3343
3384
|
}
|
|
@@ -3355,15 +3396,15 @@ The recipient is ${cap}.`));
|
|
|
3355
3396
|
});
|
|
3356
3397
|
} else {
|
|
3357
3398
|
printIngestResult(result);
|
|
3358
|
-
console.log(
|
|
3399
|
+
console.log(import_chalk9.default.dim(`
|
|
3359
3400
|
Reference this delegation on subsequent calls with:`));
|
|
3360
|
-
console.log(
|
|
3361
|
-
console.log(
|
|
3362
|
-
console.log(
|
|
3363
|
-
console.log(
|
|
3401
|
+
console.log(import_chalk9.default.dim(` heyarp delegation accept ${result.relationshipId} ${delegationId}`));
|
|
3402
|
+
console.log(import_chalk9.default.dim(` heyarp delegation decline ${result.relationshipId} ${delegationId}`));
|
|
3403
|
+
console.log(import_chalk9.default.dim(` heyarp delegation cancel ${result.relationshipId} ${delegationId}`));
|
|
3404
|
+
console.log(import_chalk9.default.dim(`
|
|
3364
3405
|
After the worker accepts, fund the escrow lock:`));
|
|
3365
|
-
console.log(
|
|
3366
|
-
console.log(
|
|
3406
|
+
console.log(import_chalk9.default.dim(` heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash <hex> ... > lock.json`));
|
|
3407
|
+
console.log(import_chalk9.default.dim(` heyarp delegation fund ${delegationId} --escrow-lock-from-file lock.json`));
|
|
3367
3408
|
}
|
|
3368
3409
|
if (opts.waitUntil && !opts.json) {
|
|
3369
3410
|
const untilPhase = parseUntilPhase(opts.waitUntil);
|
|
@@ -3385,7 +3426,7 @@ After the worker accepts, fund the escrow lock:`));
|
|
|
3385
3426
|
}
|
|
3386
3427
|
}
|
|
3387
3428
|
function registerFund(parent) {
|
|
3388
|
-
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("--ttl <seconds>", `Envelope TTL in seconds (max ${
|
|
3429
|
+
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("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk12.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(
|
|
3389
3430
|
"--json",
|
|
3390
3431
|
'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.',
|
|
3391
3432
|
false
|
|
@@ -3443,23 +3484,23 @@ async function runFund(delegationId, opts) {
|
|
|
3443
3484
|
}
|
|
3444
3485
|
if (result2.kind === "skipped_no_expected_program_id") {
|
|
3445
3486
|
console.error(
|
|
3446
|
-
|
|
3487
|
+
import_chalk9.default.yellow(
|
|
3447
3488
|
"\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."
|
|
3448
3489
|
)
|
|
3449
3490
|
);
|
|
3450
3491
|
}
|
|
3451
3492
|
}
|
|
3452
|
-
const content = { action:
|
|
3493
|
+
const content = { action: import_sdk12.DelegationActions.FUND, delegation_id: delegationId };
|
|
3453
3494
|
const body = { type: "delegation", content };
|
|
3454
3495
|
const attachments = { escrow_lock: escrowResult.attachment };
|
|
3455
|
-
progress(opts.json,
|
|
3456
|
-
progress(opts.json,
|
|
3457
|
-
progress(opts.json,
|
|
3458
|
-
progress(opts.json,
|
|
3459
|
-
progress(opts.json,
|
|
3496
|
+
progress(opts.json, import_chalk9.default.dim(`Server: ${api.serverUrl}`));
|
|
3497
|
+
progress(opts.json, import_chalk9.default.dim(`Sender: ${sender.did}`));
|
|
3498
|
+
progress(opts.json, import_chalk9.default.dim(`Recipient: ${resolved.recipientDid}`));
|
|
3499
|
+
progress(opts.json, import_chalk9.default.dim(`Relationship: ${resolved.relationshipId}`));
|
|
3500
|
+
progress(opts.json, import_chalk9.default.dim(`Delegation: ${delegationId} (action=fund)`));
|
|
3460
3501
|
{
|
|
3461
3502
|
const a = escrowResult.attachment;
|
|
3462
|
-
progress(opts.json,
|
|
3503
|
+
progress(opts.json, import_chalk9.default.dim(`Escrow lock attached: lock_id=${a.lock_id} amount=${a.amount} asset_id=${a.asset_id}`));
|
|
3463
3504
|
}
|
|
3464
3505
|
const result = await sendDelegationEnvelope({
|
|
3465
3506
|
api,
|
|
@@ -3485,7 +3526,7 @@ async function runFund(delegationId, opts) {
|
|
|
3485
3526
|
});
|
|
3486
3527
|
} else {
|
|
3487
3528
|
printIngestResult(result);
|
|
3488
|
-
console.log(
|
|
3529
|
+
console.log(import_chalk9.default.dim("\nThe worker waits for the on-chain lock to confirm (LOCKED), then begins work."));
|
|
3489
3530
|
}
|
|
3490
3531
|
if (opts.waitUntil && !opts.json) {
|
|
3491
3532
|
const untilPhase = parseUntilPhase(opts.waitUntil);
|
|
@@ -3550,7 +3591,7 @@ function registerDecline(parent) {
|
|
|
3550
3591
|
"--reason <code>",
|
|
3551
3592
|
// surface the closed enum at help time so operators
|
|
3552
3593
|
// don't have to read source to find acceptable values.
|
|
3553
|
-
`Required: decline reason code (one of: ${
|
|
3594
|
+
`Required: decline reason code (one of: ${import_sdk12.DECLINE_REASONS.join(", ")}). Carried in body.content.reason so the counterparty's reactor can branch on it.`
|
|
3554
3595
|
).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(
|
|
3555
3596
|
"--json",
|
|
3556
3597
|
'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.',
|
|
@@ -3587,7 +3628,7 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3587
3628
|
const lockWaitTimeoutSec = parseLockWaitTimeout(cmdName, opts.lockWaitTimeout);
|
|
3588
3629
|
const lockWaitIntervalSec = parseLockWaitInterval(cmdName, opts.lockWaitInterval);
|
|
3589
3630
|
let declinePayload = null;
|
|
3590
|
-
if (action ===
|
|
3631
|
+
if (action === import_sdk12.DelegationActions.DECLINE) {
|
|
3591
3632
|
const reason = parseDeclineReason(cmdName, opts.reason);
|
|
3592
3633
|
const validatedDetail = parseReasonDetail(cmdName, opts.reasonDetail);
|
|
3593
3634
|
declinePayload = validatedDetail ? { reason, reasonDetail: validatedDetail } : { reason };
|
|
@@ -3596,7 +3637,7 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3596
3637
|
const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid);
|
|
3597
3638
|
const signer = makeSigner(sender);
|
|
3598
3639
|
const resolved = await resolveDelegationRefs(cmdName, api, signer, { relationshipId, delegationId, action, selfDid: sender.did });
|
|
3599
|
-
if (resolved.state ===
|
|
3640
|
+
if (resolved.state === import_sdk12.DelegationStates.PENDING_LOCK_FINALIZATION && opts.waitForLock !== false) {
|
|
3600
3641
|
await awaitDelegationLockFinalized(cmdName, api, signer, {
|
|
3601
3642
|
relationshipId,
|
|
3602
3643
|
delegationId,
|
|
@@ -3618,10 +3659,10 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3618
3659
|
if (declinePayload.reasonDetail) content.reason_detail = declinePayload.reasonDetail;
|
|
3619
3660
|
}
|
|
3620
3661
|
const body = { type: "delegation", content };
|
|
3621
|
-
progress(opts.json,
|
|
3622
|
-
progress(opts.json,
|
|
3623
|
-
progress(opts.json,
|
|
3624
|
-
progress(opts.json,
|
|
3662
|
+
progress(opts.json, import_chalk9.default.dim(`Server: ${api.serverUrl}`));
|
|
3663
|
+
progress(opts.json, import_chalk9.default.dim(`Sender: ${sender.did}`));
|
|
3664
|
+
progress(opts.json, import_chalk9.default.dim(`Relationship: ${relationshipId}`));
|
|
3665
|
+
progress(opts.json, import_chalk9.default.dim(`Delegation: ${delegationId} (action=${action}${action === import_sdk12.DelegationActions.DECLINE ? `, reason=${content.reason}` : ""})`));
|
|
3625
3666
|
const result = await sendDelegationEnvelope({
|
|
3626
3667
|
api,
|
|
3627
3668
|
sender,
|
|
@@ -3650,9 +3691,9 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
|
|
|
3650
3691
|
async function sendDelegationEnvelope(args) {
|
|
3651
3692
|
const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
|
|
3652
3693
|
const protectedBlock = {
|
|
3653
|
-
protocol_version:
|
|
3654
|
-
purpose:
|
|
3655
|
-
message_id: (0,
|
|
3694
|
+
protocol_version: import_sdk12.CURRENT_PROTOCOL_VERSION,
|
|
3695
|
+
purpose: import_sdk12.Purpose.ENVELOPE,
|
|
3696
|
+
message_id: (0, import_sdk12.uuidV4)(),
|
|
3656
3697
|
sender_did: args.sender.did,
|
|
3657
3698
|
recipient_did: args.recipientDid,
|
|
3658
3699
|
// `relationship_id: null` matches the handshake
|
|
@@ -3661,20 +3702,20 @@ async function sendDelegationEnvelope(args) {
|
|
|
3661
3702
|
// existing relationship row.
|
|
3662
3703
|
relationship_id: null,
|
|
3663
3704
|
sender_sequence: nextSequence,
|
|
3664
|
-
sender_nonce: (0,
|
|
3665
|
-
timestamp: (0,
|
|
3666
|
-
expires_at: (0,
|
|
3705
|
+
sender_nonce: (0, import_sdk12.senderNonce)(),
|
|
3706
|
+
timestamp: (0, import_sdk12.rfc3339)(),
|
|
3707
|
+
expires_at: (0, import_sdk12.expiresAt)(args.ttlSeconds),
|
|
3667
3708
|
delivery_id: null
|
|
3668
3709
|
};
|
|
3669
3710
|
const signer = makeSigner(args.sender);
|
|
3670
|
-
const envelope = (0,
|
|
3711
|
+
const envelope = (0, import_sdk12.signEnvelope)({
|
|
3671
3712
|
protected: protectedBlock,
|
|
3672
3713
|
body: args.body,
|
|
3673
3714
|
identitySecretKey: signer.identitySecretKey,
|
|
3674
3715
|
attachments: args.attachments
|
|
3675
3716
|
});
|
|
3676
3717
|
if (args.verbose) {
|
|
3677
|
-
console.log(
|
|
3718
|
+
console.log(import_chalk9.default.bold("\nEnvelope (pre-send):"));
|
|
3678
3719
|
console.log(formatJson(envelope));
|
|
3679
3720
|
}
|
|
3680
3721
|
try {
|
|
@@ -3682,7 +3723,7 @@ async function sendDelegationEnvelope(args) {
|
|
|
3682
3723
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
3683
3724
|
return result;
|
|
3684
3725
|
} catch (err) {
|
|
3685
|
-
if (err instanceof ApiError && (0,
|
|
3726
|
+
if (err instanceof ApiError && (0, import_sdk12.isPostCommitErrorCode)(err.payload.code)) {
|
|
3686
3727
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
3687
3728
|
}
|
|
3688
3729
|
throw err;
|
|
@@ -3704,7 +3745,7 @@ async function resolveDelegationRefs(cmdName, api, signer, args) {
|
|
|
3704
3745
|
);
|
|
3705
3746
|
}
|
|
3706
3747
|
let recipientDid;
|
|
3707
|
-
if (args.action ===
|
|
3748
|
+
if (args.action === import_sdk12.DelegationActions.CANCEL) {
|
|
3708
3749
|
const firstEvents = await api.listEvents(args.relationshipId, signer, { since: 0, limit: 1 });
|
|
3709
3750
|
const handshake = firstEvents[0];
|
|
3710
3751
|
if (!handshake) {
|
|
@@ -3729,7 +3770,7 @@ async function resolveDelegationRefs(cmdName, api, signer, args) {
|
|
|
3729
3770
|
async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
3730
3771
|
const log = args.log ?? ((line) => console.log(line));
|
|
3731
3772
|
log(
|
|
3732
|
-
|
|
3773
|
+
import_chalk9.default.dim(
|
|
3733
3774
|
`
|
|
3734
3775
|
[--wait-for-lock] delegation ${args.delegationId} is awaiting on-chain lock confirmation; polling until ready (interval=${args.intervalSec}s timeout=${args.timeoutSec}s)`
|
|
3735
3776
|
)
|
|
@@ -3744,7 +3785,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3744
3785
|
after = page[page.length - 1].id;
|
|
3745
3786
|
}
|
|
3746
3787
|
};
|
|
3747
|
-
const outcome = await (0,
|
|
3788
|
+
const outcome = await (0, import_sdk12.pollUntil)({
|
|
3748
3789
|
fetch: fetchRow,
|
|
3749
3790
|
// Match on either "row not found at all" OR "state moved
|
|
3750
3791
|
// past pending_lock_finalization". The post-poll branch
|
|
@@ -3754,7 +3795,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3754
3795
|
// rows return cleanly. Polling on null would loop pointlessly
|
|
3755
3796
|
// until the deadline fires and surface a misleading "timed
|
|
3756
3797
|
// out" message for what's actually a wrong-id problem.
|
|
3757
|
-
predicate: (row2) => row2 === null || row2.state !==
|
|
3798
|
+
predicate: (row2) => row2 === null || row2.state !== import_sdk12.DelegationStates.PENDING_LOCK_FINALIZATION,
|
|
3758
3799
|
intervalMs: args.intervalSec * 1e3,
|
|
3759
3800
|
timeoutMs: args.timeoutSec * 1e3,
|
|
3760
3801
|
// Swallow ONLY transient errors. A 4xx during the poll is a
|
|
@@ -3768,7 +3809,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3768
3809
|
if (err instanceof ApiError && err.status >= 400 && err.status < 500) {
|
|
3769
3810
|
throw err;
|
|
3770
3811
|
}
|
|
3771
|
-
log(
|
|
3812
|
+
log(import_chalk9.default.dim(` poll: transient fetch error (${err instanceof Error ? err.message : String(err)})`));
|
|
3772
3813
|
}
|
|
3773
3814
|
});
|
|
3774
3815
|
if (outcome.kind === "timeout") {
|
|
@@ -3785,12 +3826,12 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
|
|
|
3785
3826
|
`${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}\`.`
|
|
3786
3827
|
);
|
|
3787
3828
|
}
|
|
3788
|
-
if (row.state !==
|
|
3829
|
+
if (row.state !== import_sdk12.DelegationStates.OFFERED) {
|
|
3789
3830
|
throw new Error(
|
|
3790
3831
|
`${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.`
|
|
3791
3832
|
);
|
|
3792
3833
|
}
|
|
3793
|
-
log(
|
|
3834
|
+
log(import_chalk9.default.dim(`[--wait-for-lock] delegation ${args.delegationId} ready (state=${row.state}); proceeding with ${args.action}.`));
|
|
3794
3835
|
return row;
|
|
3795
3836
|
}
|
|
3796
3837
|
function parseLockWaitTimeout(cmdName, raw) {
|
|
@@ -3816,12 +3857,12 @@ function parseLockWaitInterval(cmdName, raw) {
|
|
|
3816
3857
|
return n;
|
|
3817
3858
|
}
|
|
3818
3859
|
function printIngestResult(result) {
|
|
3819
|
-
console.log(
|
|
3820
|
-
console.log(`${
|
|
3821
|
-
console.log(`${
|
|
3822
|
-
console.log(`${
|
|
3823
|
-
console.log(`${
|
|
3824
|
-
console.log(`${
|
|
3860
|
+
console.log(import_chalk9.default.green("\nDelivered."));
|
|
3861
|
+
console.log(`${import_chalk9.default.bold("Event id")}: ${import_chalk9.default.cyan(result.eventId)}`);
|
|
3862
|
+
console.log(`${import_chalk9.default.bold("Relationship id")}: ${import_chalk9.default.cyan(result.relationshipId)}`);
|
|
3863
|
+
console.log(`${import_chalk9.default.bold("Chain index")}: ${import_chalk9.default.cyan(String(result.relationshipEventIndex))}`);
|
|
3864
|
+
console.log(`${import_chalk9.default.bold("Server timestamp")}: ${import_chalk9.default.cyan(result.serverTimestamp)}`);
|
|
3865
|
+
console.log(`${import_chalk9.default.bold("Server event hash")}: ${import_chalk9.default.cyan(result.serverEventHash)}`);
|
|
3825
3866
|
}
|
|
3826
3867
|
function parseOfferTerms(cmdName, opts) {
|
|
3827
3868
|
const out = {};
|
|
@@ -3845,7 +3886,7 @@ function parseOfferTerms(cmdName, opts) {
|
|
|
3845
3886
|
if (opts.amount) {
|
|
3846
3887
|
out.amount = opts.amount;
|
|
3847
3888
|
if (!opts.currency) {
|
|
3848
|
-
throw new Error(`${cmdName}: --amount requires --currency. Shorthand: ${
|
|
3889
|
+
throw new Error(`${cmdName}: --amount requires --currency. Shorthand: ${import_sdk12.WELL_KNOWN_ASSET_KEYS.join(", ")}, or raw CAIP-19 + --currency-decimals.`);
|
|
3849
3890
|
}
|
|
3850
3891
|
out.currency = buildAssetIdentifier(cmdName, DELEGATION_CURRENCY_FLAGS, opts.currency, opts.currencyDecimals, opts.currencySymbol);
|
|
3851
3892
|
} else if (opts.currency) {
|
|
@@ -3868,7 +3909,7 @@ function resolveOfferDelegationId(rawCliId, escrow) {
|
|
|
3868
3909
|
cliId = rawCliId.toLowerCase();
|
|
3869
3910
|
}
|
|
3870
3911
|
if (escrow === void 0) {
|
|
3871
|
-
return cliId ?? (0,
|
|
3912
|
+
return cliId ?? (0, import_sdk12.uuidV4)();
|
|
3872
3913
|
}
|
|
3873
3914
|
if (escrow.delegationIdFromLock !== void 0) {
|
|
3874
3915
|
const fileId = escrow.delegationIdFromLock;
|
|
@@ -3893,20 +3934,15 @@ function requireUuidNormalised(cmdName, raw, label) {
|
|
|
3893
3934
|
requireUuid2(cmdName, raw, label);
|
|
3894
3935
|
return raw.toLowerCase();
|
|
3895
3936
|
}
|
|
3896
|
-
function requireDid(cmdName, did, label) {
|
|
3897
|
-
if (typeof did !== "string" || !did.startsWith("did:arp:") || did.length <= "did:arp:".length) {
|
|
3898
|
-
throw new Error(`${cmdName}: ${label} must look like 'did:arp:...' (got '${did}')`);
|
|
3899
|
-
}
|
|
3900
|
-
}
|
|
3901
3937
|
function collectRepeated(value, previous) {
|
|
3902
3938
|
return [...previous, value];
|
|
3903
3939
|
}
|
|
3904
3940
|
function parseDeclineReason(cmdName, raw) {
|
|
3905
3941
|
if (raw === void 0 || raw === "") {
|
|
3906
|
-
throw new Error(`${cmdName}: --reason is required when declining (one of: ${
|
|
3942
|
+
throw new Error(`${cmdName}: --reason is required when declining (one of: ${import_sdk12.DECLINE_REASONS.join(", ")})`);
|
|
3907
3943
|
}
|
|
3908
|
-
if (!(0,
|
|
3909
|
-
throw new Error(`${cmdName}: --reason must be one of ${
|
|
3944
|
+
if (!(0, import_sdk12.isDeclineReason)(raw)) {
|
|
3945
|
+
throw new Error(`${cmdName}: --reason must be one of ${import_sdk12.DECLINE_REASONS.join(", ")} (got '${raw}')`);
|
|
3910
3946
|
}
|
|
3911
3947
|
return raw;
|
|
3912
3948
|
}
|
|
@@ -3921,10 +3957,10 @@ function parseReasonDetail(cmdName, raw) {
|
|
|
3921
3957
|
return raw;
|
|
3922
3958
|
}
|
|
3923
3959
|
function buildAssetIdentifier(cmdName, labels, rawCurrency, rawDecimals, rawSymbol) {
|
|
3924
|
-
const resolved = (0,
|
|
3960
|
+
const resolved = (0, import_sdk12.resolveAsset)(rawCurrency);
|
|
3925
3961
|
if (!resolved) {
|
|
3926
3962
|
throw new Error(
|
|
3927
|
-
`${cmdName}: ${labels.currencyFlag} '${rawCurrency}' is not a known shorthand or a valid CAIP-19 string. Shorthand: ${
|
|
3963
|
+
`${cmdName}: ${labels.currencyFlag} '${rawCurrency}' is not a known shorthand or a valid CAIP-19 string. Shorthand: ${import_sdk12.WELL_KNOWN_ASSET_KEYS.join(", ")}. Or pass a raw CAIP-19 id (e.g. "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/spl:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") with ${labels.decimalsFlag}.`
|
|
3928
3964
|
);
|
|
3929
3965
|
}
|
|
3930
3966
|
let decimals = resolved.decimals;
|
|
@@ -3933,20 +3969,20 @@ function buildAssetIdentifier(cmdName, labels, rawCurrency, rawDecimals, rawSymb
|
|
|
3933
3969
|
throw new Error(`${cmdName}: ${labels.currencyFlag} is a raw CAIP-19 string; ${labels.decimalsFlag} (0-18) is required to convert amounts to base units.`);
|
|
3934
3970
|
}
|
|
3935
3971
|
const parsed = Number(rawDecimals);
|
|
3936
|
-
if (!Number.isInteger(parsed) || parsed <
|
|
3972
|
+
if (!Number.isInteger(parsed) || parsed < import_sdk12.ASSET_DECIMALS_MIN || parsed > import_sdk12.ASSET_DECIMALS_MAX) {
|
|
3937
3973
|
throw new Error(`${cmdName}: ${labels.decimalsFlag} must be an integer in [0, 18] (got '${rawDecimals}').`);
|
|
3938
3974
|
}
|
|
3939
3975
|
decimals = parsed;
|
|
3940
3976
|
} else if (rawDecimals !== void 0) {
|
|
3941
3977
|
const parsed = Number(rawDecimals);
|
|
3942
|
-
if (!Number.isInteger(parsed) || parsed <
|
|
3978
|
+
if (!Number.isInteger(parsed) || parsed < import_sdk12.ASSET_DECIMALS_MIN || parsed > import_sdk12.ASSET_DECIMALS_MAX) {
|
|
3943
3979
|
throw new Error(`${cmdName}: ${labels.decimalsFlag} must be an integer in [0, 18] (got '${rawDecimals}').`);
|
|
3944
3980
|
}
|
|
3945
3981
|
decimals = parsed;
|
|
3946
3982
|
}
|
|
3947
3983
|
let symbol = resolved.symbol;
|
|
3948
3984
|
if (rawSymbol !== void 0) {
|
|
3949
|
-
if (rawSymbol.length <
|
|
3985
|
+
if (rawSymbol.length < import_sdk12.ASSET_SYMBOL_MIN_LEN || rawSymbol.length > import_sdk12.ASSET_SYMBOL_MAX_LEN) {
|
|
3950
3986
|
throw new Error(`${cmdName}: ${labels.symbolFlag} must be 1-16 chars (got length ${rawSymbol.length}).`);
|
|
3951
3987
|
}
|
|
3952
3988
|
symbol = rawSymbol;
|
|
@@ -3960,10 +3996,10 @@ var DELEGATION_CURRENCY_FLAGS = {
|
|
|
3960
3996
|
};
|
|
3961
3997
|
|
|
3962
3998
|
// src/commands/delegations.ts
|
|
3963
|
-
var
|
|
3964
|
-
var
|
|
3999
|
+
var import_sdk13 = require("@heyanon-arp/sdk");
|
|
4000
|
+
var import_chalk10 = __toESM(require("chalk"));
|
|
3965
4001
|
init_api();
|
|
3966
|
-
var ALLOWED_STATES = /* @__PURE__ */ new Set([
|
|
4002
|
+
var ALLOWED_STATES = /* @__PURE__ */ new Set([import_sdk13.DelegationStates.OFFERED, import_sdk13.DelegationStates.ACCEPTED, import_sdk13.DelegationStates.DECLINED, import_sdk13.DelegationStates.CANCELED]);
|
|
3967
4003
|
function registerDelegationsCommand(root) {
|
|
3968
4004
|
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(
|
|
3969
4005
|
"--verbose",
|
|
@@ -3983,9 +4019,9 @@ async function runDelegations(relationshipId, opts) {
|
|
|
3983
4019
|
const state = parseState(opts.state);
|
|
3984
4020
|
const api = new ArpApiClient(opts.server);
|
|
3985
4021
|
const sender = resolveSenderAgent("delegations", opts.server, opts.fromDid);
|
|
3986
|
-
progress(opts.json,
|
|
3987
|
-
progress(opts.json,
|
|
3988
|
-
progress(opts.json,
|
|
4022
|
+
progress(opts.json, import_chalk10.default.dim(`Server: ${api.serverUrl}`));
|
|
4023
|
+
progress(opts.json, import_chalk10.default.dim(`Signer: ${sender.did}`));
|
|
4024
|
+
progress(opts.json, import_chalk10.default.dim(`Relationship: ${relationshipId}`));
|
|
3989
4025
|
const query = { limit };
|
|
3990
4026
|
if (state) query.state = state;
|
|
3991
4027
|
if (opts.after) query.after = opts.after;
|
|
@@ -3996,7 +4032,7 @@ async function runDelegations(relationshipId, opts) {
|
|
|
3996
4032
|
return;
|
|
3997
4033
|
}
|
|
3998
4034
|
if (rows.length === 0) {
|
|
3999
|
-
console.log(
|
|
4035
|
+
console.log(import_chalk10.default.dim("\n(no delegations for this relationship)"));
|
|
4000
4036
|
return;
|
|
4001
4037
|
}
|
|
4002
4038
|
console.log("");
|
|
@@ -4012,19 +4048,19 @@ async function runDelegations(relationshipId, opts) {
|
|
|
4012
4048
|
}));
|
|
4013
4049
|
}
|
|
4014
4050
|
const lastId = rows[rows.length - 1].id;
|
|
4015
|
-
console.log(
|
|
4051
|
+
console.log(import_chalk10.default.dim(`
|
|
4016
4052
|
${rows.length} delegation row(s). Paginate with --after ${lastId}.`));
|
|
4017
4053
|
}
|
|
4018
4054
|
function formatDelegationLine(d, selfDid, opts = {}) {
|
|
4019
|
-
const idHead_ =
|
|
4055
|
+
const idHead_ = import_chalk10.default.bold(opts.fullIds ? d.delegationId : idHead(d.delegationId));
|
|
4020
4056
|
const state = colorState(d.state).padEnd(stateColumnWidth());
|
|
4021
|
-
const offerer = d.offererDid === selfDid ?
|
|
4057
|
+
const offerer = d.offererDid === selfDid ? import_chalk10.default.bold("me") : import_chalk10.default.dim(opts.fullIds ? d.offererDid : didHead(d.offererDid));
|
|
4022
4058
|
const amount = formatAmount(d);
|
|
4023
|
-
const title = d.title ?
|
|
4059
|
+
const title = d.title ? import_chalk10.default.dim(`"${truncate2(d.title, 40)}"`) : import_chalk10.default.dim("(no title)");
|
|
4024
4060
|
let declineSuffix = "";
|
|
4025
|
-
if (d.state ===
|
|
4061
|
+
if (d.state === import_sdk13.DelegationStates.DECLINED && d.declineReason) {
|
|
4026
4062
|
const detail = d.declineReasonDetail ? `: ${truncate2(d.declineReasonDetail, 40)}` : "";
|
|
4027
|
-
declineSuffix = ` ${
|
|
4063
|
+
declineSuffix = ` ${import_chalk10.default.dim(`(reason: ${d.declineReason}${detail})`)}`;
|
|
4028
4064
|
}
|
|
4029
4065
|
return `${idHead_} ${state} ${offerer} ${amount} ${title}${declineSuffix}`;
|
|
4030
4066
|
}
|
|
@@ -4037,35 +4073,35 @@ function colorState(s) {
|
|
|
4037
4073
|
// returns `undefined` and `formatDelegationLine` crashes with
|
|
4038
4074
|
// `TypeError: Cannot read properties of undefined (reading
|
|
4039
4075
|
// 'padEnd')` on any listing containing such a row.
|
|
4040
|
-
case
|
|
4041
|
-
return
|
|
4042
|
-
case
|
|
4043
|
-
return
|
|
4044
|
-
case
|
|
4045
|
-
return
|
|
4076
|
+
case import_sdk13.DelegationStates.OFFERED:
|
|
4077
|
+
return import_chalk10.default.yellow("offered");
|
|
4078
|
+
case import_sdk13.DelegationStates.PENDING_LOCK_FINALIZATION:
|
|
4079
|
+
return import_chalk10.default.yellow("pending_lock");
|
|
4080
|
+
case import_sdk13.DelegationStates.ACCEPTED:
|
|
4081
|
+
return import_chalk10.default.green("accepted");
|
|
4046
4082
|
// The on-chain escrow lock is confirmed. Distinct branch so a
|
|
4047
4083
|
// LOCKED row renders without hitting the defensive fallback
|
|
4048
4084
|
// (which would otherwise echo the raw state).
|
|
4049
|
-
case
|
|
4050
|
-
return
|
|
4051
|
-
case
|
|
4052
|
-
return
|
|
4053
|
-
case
|
|
4054
|
-
return
|
|
4085
|
+
case import_sdk13.DelegationStates.LOCKED:
|
|
4086
|
+
return import_chalk10.default.green("locked");
|
|
4087
|
+
case import_sdk13.DelegationStates.DECLINED:
|
|
4088
|
+
return import_chalk10.default.red("declined");
|
|
4089
|
+
case import_sdk13.DelegationStates.CANCELED:
|
|
4090
|
+
return import_chalk10.default.dim("canceled");
|
|
4055
4091
|
// Terminal escrow outcomes: completed = payee paid;
|
|
4056
4092
|
// failed = create_lock never landed; refunded = funds returned
|
|
4057
4093
|
// to the buyer (work expired / dispute closed);
|
|
4058
4094
|
// dispute_resolved = operator ruled.
|
|
4059
|
-
case
|
|
4060
|
-
return
|
|
4061
|
-
case
|
|
4062
|
-
return
|
|
4063
|
-
case
|
|
4064
|
-
return
|
|
4065
|
-
case
|
|
4066
|
-
return
|
|
4067
|
-
case
|
|
4068
|
-
return
|
|
4095
|
+
case import_sdk13.DelegationStates.COMPLETED:
|
|
4096
|
+
return import_chalk10.default.green("completed");
|
|
4097
|
+
case import_sdk13.DelegationStates.FAILED:
|
|
4098
|
+
return import_chalk10.default.red("failed");
|
|
4099
|
+
case import_sdk13.DelegationStates.REFUNDED:
|
|
4100
|
+
return import_chalk10.default.red("refunded");
|
|
4101
|
+
case import_sdk13.DelegationStates.DISPUTING:
|
|
4102
|
+
return import_chalk10.default.yellow("disputing");
|
|
4103
|
+
case import_sdk13.DelegationStates.DISPUTE_RESOLVED:
|
|
4104
|
+
return import_chalk10.default.red("dispute_resolved");
|
|
4069
4105
|
default: {
|
|
4070
4106
|
const _exhaustive = s;
|
|
4071
4107
|
void _exhaustive;
|
|
@@ -4077,9 +4113,9 @@ function stateColumnWidth() {
|
|
|
4077
4113
|
return 12;
|
|
4078
4114
|
}
|
|
4079
4115
|
function formatAmount(d) {
|
|
4080
|
-
if (!d.amount) return
|
|
4116
|
+
if (!d.amount) return import_chalk10.default.dim("(no amount)");
|
|
4081
4117
|
const currency = d.currency ? d.currency.symbol ?? d.currency.assetId : "?";
|
|
4082
|
-
return
|
|
4118
|
+
return import_chalk10.default.cyan(`${d.amount} ${currency}`);
|
|
4083
4119
|
}
|
|
4084
4120
|
function idHead(id) {
|
|
4085
4121
|
if (id.length <= 12) return id;
|
|
@@ -4110,7 +4146,7 @@ function parseLimit2(raw) {
|
|
|
4110
4146
|
}
|
|
4111
4147
|
|
|
4112
4148
|
// src/commands/did-doc.ts
|
|
4113
|
-
var
|
|
4149
|
+
var import_sdk14 = require("@heyanon-arp/sdk");
|
|
4114
4150
|
init_api();
|
|
4115
4151
|
function registerDidDocCommand(root) {
|
|
4116
4152
|
root.command("did-doc").description(
|
|
@@ -4119,7 +4155,7 @@ function registerDidDocCommand(root) {
|
|
|
4119
4155
|
"--field <path>",
|
|
4120
4156
|
"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."
|
|
4121
4157
|
).action(async (did, opts) => {
|
|
4122
|
-
if (!(0,
|
|
4158
|
+
if (!(0, import_sdk14.isValidDid)(did)) {
|
|
4123
4159
|
throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
|
|
4124
4160
|
}
|
|
4125
4161
|
if (opts.json && opts.field !== void 0) {
|
|
@@ -4231,8 +4267,8 @@ function describeShape(value) {
|
|
|
4231
4267
|
}
|
|
4232
4268
|
|
|
4233
4269
|
// src/commands/doctor.ts
|
|
4234
|
-
var
|
|
4235
|
-
var
|
|
4270
|
+
var import_sdk15 = require("@heyanon-arp/sdk");
|
|
4271
|
+
var import_chalk11 = __toESM(require("chalk"));
|
|
4236
4272
|
init_api();
|
|
4237
4273
|
function registerDoctorCommand(root) {
|
|
4238
4274
|
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) => {
|
|
@@ -4241,7 +4277,7 @@ function registerDoctorCommand(root) {
|
|
|
4241
4277
|
}
|
|
4242
4278
|
var LISTENING_THRESHOLD_SECONDS = 15 * 60;
|
|
4243
4279
|
async function runDoctor(did, opts) {
|
|
4244
|
-
if (!(0,
|
|
4280
|
+
if (!(0, import_sdk15.isValidDid)(did)) {
|
|
4245
4281
|
throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
|
|
4246
4282
|
}
|
|
4247
4283
|
const api = new ArpApiClient(opts.server);
|
|
@@ -4325,39 +4361,39 @@ async function probe(api, did) {
|
|
|
4325
4361
|
}
|
|
4326
4362
|
function formatDoctorReport(r) {
|
|
4327
4363
|
const lines = [];
|
|
4328
|
-
lines.push(`${
|
|
4329
|
-
lines.push(`${
|
|
4364
|
+
lines.push(`${import_chalk11.default.dim("Server:")} ${r.server}`);
|
|
4365
|
+
lines.push(`${import_chalk11.default.dim("Target DID:")} ${r.did}`);
|
|
4330
4366
|
if (!r.didDocument.found) {
|
|
4331
|
-
lines.push(`${
|
|
4367
|
+
lines.push(`${import_chalk11.default.dim("DID doc:")} ${import_chalk11.default.red("\u2717")} not found`);
|
|
4332
4368
|
} else {
|
|
4333
4369
|
const registered = r.didDocument.registeredAt ? ` (registered ${r.didDocument.registeredAt})` : "";
|
|
4334
|
-
lines.push(`${
|
|
4370
|
+
lines.push(`${import_chalk11.default.dim("DID doc:")} ${import_chalk11.default.green("\u2713")} resolved${registered}`);
|
|
4335
4371
|
}
|
|
4336
4372
|
if (r.activity) {
|
|
4337
4373
|
if (r.activity.lastEventAt === null) {
|
|
4338
|
-
lines.push(`${
|
|
4374
|
+
lines.push(`${import_chalk11.default.dim("Activity:")} ${import_chalk11.default.dim("(no events ever \u2014 fresh agent)")}`);
|
|
4339
4375
|
} else {
|
|
4340
4376
|
const ageMin = r.activity.ageSeconds !== null ? Math.floor(r.activity.ageSeconds / 60) : null;
|
|
4341
4377
|
const ageStr = ageMin !== null && ageMin > 0 ? `${ageMin}m ago` : `${r.activity.ageSeconds}s ago`;
|
|
4342
|
-
lines.push(`${
|
|
4378
|
+
lines.push(`${import_chalk11.default.dim("Activity:")} last event ${ageStr} (${r.activity.lastEventAt})`);
|
|
4343
4379
|
}
|
|
4344
4380
|
if (r.activity.lastSeenAt !== null && r.activity.lastSeenAt !== void 0) {
|
|
4345
4381
|
const seenMin = r.activity.seenAgeSeconds !== null && r.activity.seenAgeSeconds !== void 0 ? Math.floor(r.activity.seenAgeSeconds / 60) : null;
|
|
4346
4382
|
const seenStr = seenMin !== null && seenMin > 0 ? `${seenMin}m ago` : `${r.activity.seenAgeSeconds}s ago`;
|
|
4347
|
-
lines.push(`${
|
|
4383
|
+
lines.push(`${import_chalk11.default.dim("Last seen:")} signed request ${seenStr} (${r.activity.lastSeenAt})`);
|
|
4348
4384
|
}
|
|
4349
4385
|
if (r.activity.inboxStreamActive === true) {
|
|
4350
|
-
lines.push(`${
|
|
4386
|
+
lines.push(`${import_chalk11.default.dim("Inbox SSE:")} ${import_chalk11.default.green("\u2713")} active subscription on the central server`);
|
|
4351
4387
|
}
|
|
4352
4388
|
}
|
|
4353
|
-
const verdictColor = r.verdict === "LISTENING" ?
|
|
4389
|
+
const verdictColor = r.verdict === "LISTENING" ? import_chalk11.default.green : r.verdict === "DORMANT" ? import_chalk11.default.red : import_chalk11.default.yellow;
|
|
4354
4390
|
lines.push("");
|
|
4355
|
-
lines.push(`${
|
|
4391
|
+
lines.push(`${import_chalk11.default.bold("Verdict:")} ${verdictColor(r.verdict)} \u2014 ${r.reason}`);
|
|
4356
4392
|
return lines.join("\n");
|
|
4357
4393
|
}
|
|
4358
4394
|
|
|
4359
4395
|
// src/commands/envelope.ts
|
|
4360
|
-
var
|
|
4396
|
+
var import_chalk12 = __toESM(require("chalk"));
|
|
4361
4397
|
init_api();
|
|
4362
4398
|
function registerEnvelopeCommand(root) {
|
|
4363
4399
|
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("--json", "Machine-readable: emit only the envelope JSON object on stdout (no prelude, no chalk). Pipe-safe.", false).action(async (eventId, opts) => {
|
|
@@ -4368,9 +4404,9 @@ async function runEnvelope(eventId, opts) {
|
|
|
4368
4404
|
const api = new ArpApiClient(opts.server);
|
|
4369
4405
|
const sender = resolveSenderAgent("envelope", opts.server, opts.fromDid);
|
|
4370
4406
|
if (!opts.json) {
|
|
4371
|
-
console.log(
|
|
4372
|
-
console.log(
|
|
4373
|
-
console.log(
|
|
4407
|
+
console.log(import_chalk12.default.dim(`Server: ${api.serverUrl}`));
|
|
4408
|
+
console.log(import_chalk12.default.dim(`Signer: ${sender.did}`));
|
|
4409
|
+
console.log(import_chalk12.default.dim(`Event: ${eventId}`));
|
|
4374
4410
|
}
|
|
4375
4411
|
const signer = makeSigner(sender);
|
|
4376
4412
|
const event = await api.getEvent(sender.did, eventId, signer);
|
|
@@ -4379,29 +4415,29 @@ async function runEnvelope(eventId, opts) {
|
|
|
4379
4415
|
return;
|
|
4380
4416
|
}
|
|
4381
4417
|
console.log("");
|
|
4382
|
-
console.log(
|
|
4418
|
+
console.log(import_chalk12.default.bold("Envelope:"));
|
|
4383
4419
|
console.log(formatJson(event));
|
|
4384
4420
|
console.log("");
|
|
4385
4421
|
console.log(formatHints(event));
|
|
4386
4422
|
}
|
|
4387
4423
|
function formatHints(event) {
|
|
4388
4424
|
const lines = [];
|
|
4389
|
-
lines.push(`${
|
|
4390
|
-
lines.push(`${
|
|
4391
|
-
lines.push(`${
|
|
4392
|
-
lines.push(`${
|
|
4425
|
+
lines.push(`${import_chalk12.default.dim("relationshipId:")} ${import_chalk12.default.cyan(event.relationshipId)}`);
|
|
4426
|
+
lines.push(`${import_chalk12.default.dim("serverEventHash:")} ${import_chalk12.default.cyan(event.serverEventHash)}`);
|
|
4427
|
+
lines.push(`${import_chalk12.default.dim("eventId:")} ${import_chalk12.default.cyan(event.eventId)}`);
|
|
4428
|
+
lines.push(`${import_chalk12.default.dim("relationshipEventIndex:")} ${import_chalk12.default.cyan(String(event.relationshipEventIndex))}`);
|
|
4393
4429
|
return lines.join("\n");
|
|
4394
4430
|
}
|
|
4395
4431
|
|
|
4396
4432
|
// src/commands/escrow.ts
|
|
4397
|
-
var
|
|
4433
|
+
var import_sdk17 = require("@heyanon-arp/sdk");
|
|
4398
4434
|
var import_utils2 = require("@noble/hashes/utils");
|
|
4399
|
-
var
|
|
4435
|
+
var import_chalk13 = __toESM(require("chalk"));
|
|
4400
4436
|
init_api();
|
|
4401
4437
|
|
|
4402
4438
|
// src/commands/escrow-actions.ts
|
|
4403
4439
|
var import_node_crypto = require("crypto");
|
|
4404
|
-
var
|
|
4440
|
+
var import_sdk16 = require("@heyanon-arp/sdk");
|
|
4405
4441
|
var import_web33 = require("@solana/web3.js");
|
|
4406
4442
|
init_api();
|
|
4407
4443
|
var FEE_BUFFER_LAMPORTS = 10000000n;
|
|
@@ -4415,7 +4451,7 @@ async function setup(cmd, delegationIdArg, opts) {
|
|
|
4415
4451
|
const delegationId = normaliseDelegationId(delegationIdArg);
|
|
4416
4452
|
const fetched = await fetchLockAccount(conn, programId, delegationId);
|
|
4417
4453
|
if (!fetched) {
|
|
4418
|
-
const lockPda = deriveLockPda(programId, (0,
|
|
4454
|
+
const lockPda = deriveLockPda(programId, (0, import_sdk16.deriveLockId)(delegationId)).toBase58();
|
|
4419
4455
|
throw new Error(
|
|
4420
4456
|
`${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.`
|
|
4421
4457
|
);
|
|
@@ -4440,7 +4476,7 @@ function nowSecs() {
|
|
|
4440
4476
|
function deadlinePassed(ctx) {
|
|
4441
4477
|
return ctx.lock.expiry > 0n && nowSecs() >= ctx.lock.expiry;
|
|
4442
4478
|
}
|
|
4443
|
-
var SYSTEM_PROGRAM_B58 =
|
|
4479
|
+
var SYSTEM_PROGRAM_B58 = import_sdk16.SYSTEM_PROGRAM_ID_BASE58;
|
|
4444
4480
|
function effectiveFeeRecipient(lock) {
|
|
4445
4481
|
if (lock.feeRecipientAtLock !== SYSTEM_PROGRAM_B58) return new import_web33.PublicKey(lock.feeRecipientAtLock);
|
|
4446
4482
|
if (lock.treasuryAtLock && lock.treasuryAtLock !== SYSTEM_PROGRAM_B58) return new import_web33.PublicKey(lock.treasuryAtLock);
|
|
@@ -4502,7 +4538,7 @@ function emit(ctx, action, signature, extra = {}) {
|
|
|
4502
4538
|
}
|
|
4503
4539
|
async function acceptHandler(delegationId, opts) {
|
|
4504
4540
|
const ctx = await setup("escrow accept", delegationId, opts);
|
|
4505
|
-
requireState(ctx, [
|
|
4541
|
+
requireState(ctx, [import_sdk16.LockStates.CREATED], "Accept is only possible before any other transition; if it shows in_progress you already accepted.");
|
|
4506
4542
|
requireSigner(ctx, "payee", ctx.lock.payee);
|
|
4507
4543
|
const stake = ctx.lock.workerStakeAtLock;
|
|
4508
4544
|
await preflightLamports(ctx, stake, `the worker stake (${stake} lamports, returned when the lock settles in your favour)`);
|
|
@@ -4512,7 +4548,7 @@ async function acceptHandler(delegationId, opts) {
|
|
|
4512
4548
|
}
|
|
4513
4549
|
async function submitWorkHandler(delegationId, opts) {
|
|
4514
4550
|
const ctx = await setup("escrow submit-work", delegationId, opts);
|
|
4515
|
-
requireState(ctx, [
|
|
4551
|
+
requireState(ctx, [import_sdk16.LockStates.IN_PROGRESS], "Submit needs an accepted lock ('created' \u2192 run `heyarp escrow accept` first; terminal \u2192 the cycle already ended).");
|
|
4516
4552
|
requireSigner(ctx, "payee", ctx.lock.payee);
|
|
4517
4553
|
if (deadlinePassed(ctx)) {
|
|
4518
4554
|
throw new Error(
|
|
@@ -4523,7 +4559,7 @@ async function submitWorkHandler(delegationId, opts) {
|
|
|
4523
4559
|
let reviewDeadline = null;
|
|
4524
4560
|
try {
|
|
4525
4561
|
const fresh = await fetchLockAccount(ctx.conn, ctx.programId, ctx.delegationId);
|
|
4526
|
-
if (fresh && fresh.lock.state ===
|
|
4562
|
+
if (fresh && fresh.lock.state === import_sdk16.LockStates.SUBMITTED && fresh.lock.expiry > 0n) {
|
|
4527
4563
|
reviewDeadline = new Date(Number(fresh.lock.expiry) * 1e3).toISOString();
|
|
4528
4564
|
}
|
|
4529
4565
|
} catch {
|
|
@@ -4536,24 +4572,24 @@ async function submitWorkHandler(delegationId, opts) {
|
|
|
4536
4572
|
}
|
|
4537
4573
|
async function claimHandler(delegationId, opts) {
|
|
4538
4574
|
const ctx = await setup("escrow claim", delegationId, opts);
|
|
4539
|
-
requireState(ctx, [
|
|
4575
|
+
requireState(ctx, [import_sdk16.LockStates.SUBMITTED], "Claim needs submitted work ('in_progress' \u2192 the worker must `escrow submit-work` first; 'paid' \u2192 already claimed).");
|
|
4540
4576
|
const me = ctx.keypair.publicKey.toBase58();
|
|
4541
4577
|
let role;
|
|
4542
4578
|
if (me === ctx.lock.payer) {
|
|
4543
|
-
role =
|
|
4579
|
+
role = import_sdk16.EscrowReleaseMethods.BUYER_APPROVED;
|
|
4544
4580
|
} else if (me === ctx.lock.payee) {
|
|
4545
4581
|
if (!deadlinePassed(ctx)) {
|
|
4546
4582
|
throw new Error(
|
|
4547
4583
|
`escrow claim: the review window is still open (until ${expiryIso(ctx)}). As the worker you can self-claim only AFTER it lapses; before that the buyer must approve (or dispute).`
|
|
4548
4584
|
);
|
|
4549
4585
|
}
|
|
4550
|
-
role =
|
|
4586
|
+
role = import_sdk16.EscrowReleaseMethods.REVIEW_TIMEOUT;
|
|
4551
4587
|
} else {
|
|
4552
4588
|
throw new Error(`escrow claim: your settlement key ${me} is neither the payer (${ctx.lock.payer}) nor the payee (${ctx.lock.payee}) of this lock.`);
|
|
4553
4589
|
}
|
|
4554
4590
|
progress(
|
|
4555
4591
|
ctx.opts.json,
|
|
4556
|
-
role ===
|
|
4592
|
+
role === import_sdk16.EscrowReleaseMethods.BUYER_APPROVED ? "approving payment as the buyer \u2014 this RELEASES the escrow and is irreversible" : "self-claiming after review timeout"
|
|
4557
4593
|
);
|
|
4558
4594
|
const sig = await sendIx(
|
|
4559
4595
|
ctx,
|
|
@@ -4571,7 +4607,7 @@ async function claimHandler(delegationId, opts) {
|
|
|
4571
4607
|
}
|
|
4572
4608
|
async function cancelHandler(delegationId, opts) {
|
|
4573
4609
|
const ctx = await setup("escrow cancel", delegationId, opts);
|
|
4574
|
-
requireState(ctx, [
|
|
4610
|
+
requireState(ctx, [import_sdk16.LockStates.CREATED], "Cancel is the pre-accept exit only \u2014 once the worker accepted ('in_progress') the windows model governs.");
|
|
4575
4611
|
requireSigner(ctx, "payer", ctx.lock.payer);
|
|
4576
4612
|
const sig = await sendIx(
|
|
4577
4613
|
ctx,
|
|
@@ -4586,7 +4622,7 @@ async function cancelHandler(delegationId, opts) {
|
|
|
4586
4622
|
}
|
|
4587
4623
|
async function claimExpiredHandler(delegationId, opts) {
|
|
4588
4624
|
const ctx = await setup("escrow claim-expired", delegationId, opts);
|
|
4589
|
-
requireState(ctx, [
|
|
4625
|
+
requireState(ctx, [import_sdk16.LockStates.IN_PROGRESS], "Claim-expired recovers an accepted-but-never-submitted lock; 'submitted' work goes through claim/dispute instead.");
|
|
4590
4626
|
requireSigner(ctx, "payer", ctx.lock.payer);
|
|
4591
4627
|
if (!deadlinePassed(ctx)) {
|
|
4592
4628
|
throw new Error(`escrow claim-expired: the work window is still open (until ${expiryIso(ctx)}). The worker can still submit; the chain will reject this claim until then.`);
|
|
@@ -4604,7 +4640,7 @@ async function claimExpiredHandler(delegationId, opts) {
|
|
|
4604
4640
|
}
|
|
4605
4641
|
async function disputeOpenHandler(delegationId, opts) {
|
|
4606
4642
|
const ctx = await setup("escrow dispute open", delegationId, opts);
|
|
4607
|
-
requireState(ctx, [
|
|
4643
|
+
requireState(ctx, [import_sdk16.LockStates.SUBMITTED], "Disputes open against SUBMITTED work, inside the review window.");
|
|
4608
4644
|
requireSigner(ctx, "payer", ctx.lock.payer);
|
|
4609
4645
|
if (deadlinePassed(ctx)) {
|
|
4610
4646
|
throw new Error(
|
|
@@ -4619,7 +4655,7 @@ async function disputeOpenHandler(delegationId, opts) {
|
|
|
4619
4655
|
}
|
|
4620
4656
|
async function disputeCloseHandler(delegationId, opts) {
|
|
4621
4657
|
const ctx = await setup("escrow dispute close", delegationId, opts);
|
|
4622
|
-
requireState(ctx, [
|
|
4658
|
+
requireState(ctx, [import_sdk16.LockStates.DISPUTING], "Close only applies to an OPEN dispute that the operator never resolved.");
|
|
4623
4659
|
const me = ctx.keypair.publicKey.toBase58();
|
|
4624
4660
|
if (me !== ctx.lock.payer && me !== ctx.lock.payee) {
|
|
4625
4661
|
throw new Error(`escrow dispute close: your settlement key ${me} is neither party of this lock.`);
|
|
@@ -4644,7 +4680,7 @@ async function disputeCloseHandler(delegationId, opts) {
|
|
|
4644
4680
|
}
|
|
4645
4681
|
async function disputeResolveHandler(delegationId, opts) {
|
|
4646
4682
|
const ctx = await setup("escrow dispute resolve", delegationId, opts);
|
|
4647
|
-
requireState(ctx, [
|
|
4683
|
+
requireState(ctx, [import_sdk16.LockStates.DISPUTING], "Resolve only applies to an OPEN dispute, inside the dispute window.");
|
|
4648
4684
|
if (deadlinePassed(ctx)) {
|
|
4649
4685
|
throw new Error(
|
|
4650
4686
|
`escrow dispute resolve: the dispute window lapsed at ${expiryIso(ctx)} \u2014 the chain rejects late rulings (LockExpired); either party can now \`escrow dispute close\` instead.`
|
|
@@ -4688,7 +4724,7 @@ async function showHandler(delegationId, opts) {
|
|
|
4688
4724
|
jsonOut({
|
|
4689
4725
|
delegation_id: normalised.slice("del_".length),
|
|
4690
4726
|
lock_exists: false,
|
|
4691
|
-
lock_pda: deriveLockPda(programId, (0,
|
|
4727
|
+
lock_pda: deriveLockPda(programId, (0, import_sdk16.deriveLockId)(normalised)).toBase58(),
|
|
4692
4728
|
rpc_url: redactRpcUrl(rpcUrl)
|
|
4693
4729
|
});
|
|
4694
4730
|
return;
|
|
@@ -4765,7 +4801,7 @@ function registerEscrowCommands(root) {
|
|
|
4765
4801
|
"Compute canonical condition_hash (32-byte hex) for `heyarp wallet create-lock --condition-hash <hex>` from the DELEGATION terms. Projects the flags to the canonical subset and hashes via SDK deriveDelegationConditionHash \u2014 no server fetch. The SAME terms MUST go into `delegation offer` or the server rejects the lock (ESC_LOCK_CONDITION_HASH_MISMATCH)."
|
|
4766
4802
|
).requiredOption("--delegation-id <id>", "Delegation UUID this lock binds (drives the on-chain lock_id + the condition_hash identity binding)").requiredOption("--scope <text>", "scope_summary \u2014 short prose describing the agreed work").option(
|
|
4767
4803
|
"--currency <s>",
|
|
4768
|
-
`Asset identifier bound into the hash: shorthand (${
|
|
4804
|
+
`Asset identifier bound into the hash: shorthand (${import_sdk17.WELL_KNOWN_ASSET_KEYS.join("|")}) OR raw CAIP-19 string. Optional but must match the offer's --currency.`
|
|
4769
4805
|
).option("--currency-decimals <n>", "Decimal places (0-18). Required only when --currency is raw CAIP-19.").option("--currency-symbol <s>", 'Optional UI hint ("USDC", "SOL"). Max 16 chars.').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("--json", "Machine-readable JSON: {delegation_id, condition_hash_hex, projected_subset}", false).action(async (opts) => {
|
|
4770
4806
|
await runDeriveConditionHash(opts);
|
|
4771
4807
|
});
|
|
@@ -4779,7 +4815,7 @@ async function runEscrowInfo(opts) {
|
|
|
4779
4815
|
const api = new ArpApiClient(opts.server);
|
|
4780
4816
|
const status = await api.getEscrowConfig();
|
|
4781
4817
|
if (opts.json) {
|
|
4782
|
-
progress(true,
|
|
4818
|
+
progress(true, import_chalk13.default.dim(`Server: ${api.serverUrl}`));
|
|
4783
4819
|
jsonOut(status);
|
|
4784
4820
|
} else {
|
|
4785
4821
|
console.log(formatEscrowConfigStatus(api.serverUrl, status));
|
|
@@ -4788,35 +4824,35 @@ async function runEscrowInfo(opts) {
|
|
|
4788
4824
|
function formatEscrowConfigStatus(serverUrl, s) {
|
|
4789
4825
|
const lines = [];
|
|
4790
4826
|
const win = (secs) => secs % 3600 === 0 ? `${secs / 3600}h` : secs % 60 === 0 ? `${secs / 60}m` : `${secs}s`;
|
|
4791
|
-
lines.push(`${
|
|
4792
|
-
lines.push(`${
|
|
4793
|
-
lines.push(`${
|
|
4794
|
-
lines.push(`${
|
|
4795
|
-
lines.push(`${
|
|
4827
|
+
lines.push(`${import_chalk13.default.dim("Server:")} ${serverUrl}`);
|
|
4828
|
+
lines.push(`${import_chalk13.default.dim("Program ID:")} ${s.programId}`);
|
|
4829
|
+
lines.push(`${import_chalk13.default.dim("Admin:")} ${s.admin}`);
|
|
4830
|
+
lines.push(`${import_chalk13.default.dim("Treasury:")} ${s.treasury}`);
|
|
4831
|
+
lines.push(`${import_chalk13.default.dim("Paused:")} ${s.paused ? import_chalk13.default.yellow("YES (new locks rejected)") : import_chalk13.default.green("no")}`);
|
|
4796
4832
|
lines.push("");
|
|
4797
|
-
lines.push(
|
|
4798
|
-
lines.push(` ${
|
|
4799
|
-
lines.push(` ${
|
|
4800
|
-
lines.push(` ${
|
|
4833
|
+
lines.push(import_chalk13.default.bold("Windows (rolling deadlines):"));
|
|
4834
|
+
lines.push(` ${import_chalk13.default.dim("work:")} ${win(s.workWindowSecs)} ${import_chalk13.default.dim("(accept \u2192 submit_work)")}`);
|
|
4835
|
+
lines.push(` ${import_chalk13.default.dim("review:")} ${win(s.reviewWindowSecs)} ${import_chalk13.default.dim("(submit_work \u2192 buyer approve / worker self-claim)")}`);
|
|
4836
|
+
lines.push(` ${import_chalk13.default.dim("dispute:")} ${win(s.disputeWindowSecs)} ${import_chalk13.default.dim("(open_dispute \u2192 operator resolve / timeout close)")}`);
|
|
4801
4837
|
lines.push("");
|
|
4802
|
-
lines.push(
|
|
4803
|
-
lines.push(` ${
|
|
4804
|
-
lines.push(` ${
|
|
4838
|
+
lines.push(import_chalk13.default.bold("Stakes:"));
|
|
4839
|
+
lines.push(` ${import_chalk13.default.dim("worker stake:")} ${s.workerStakeLamports} lamports ${import_chalk13.default.dim("(escrowed at accept_lock, returned on completion)")}`);
|
|
4840
|
+
lines.push(` ${import_chalk13.default.dim("operator dispute fee:")} ${s.operatorDisputeFeeLamports} lamports`);
|
|
4805
4841
|
lines.push("");
|
|
4806
|
-
lines.push(
|
|
4842
|
+
lines.push(import_chalk13.default.bold("Protocol fee:"));
|
|
4807
4843
|
if (!s.feeEnabled || s.feeBps === 0) {
|
|
4808
|
-
lines.push(` ${
|
|
4809
|
-
lines.push(` ${
|
|
4810
|
-
lines.push(` ${
|
|
4844
|
+
lines.push(` ${import_chalk13.default.green("DISABLED")}`);
|
|
4845
|
+
lines.push(` ${import_chalk13.default.dim("fee_bps:")} ${s.feeBps}`);
|
|
4846
|
+
lines.push(` ${import_chalk13.default.dim("fee_recipient:")} ${s.feeRecipient}`);
|
|
4811
4847
|
lines.push("");
|
|
4812
|
-
lines.push(
|
|
4848
|
+
lines.push(import_chalk13.default.dim(` New locks will snapshot fee_bps=0 \u2014 payee receives 100% on claim.`));
|
|
4813
4849
|
} else {
|
|
4814
4850
|
const pct = (s.feeBps / 100).toFixed(2);
|
|
4815
|
-
lines.push(` ${
|
|
4816
|
-
lines.push(` ${
|
|
4851
|
+
lines.push(` ${import_chalk13.default.yellow("ENABLED")} \u2014 ${pct}% of payee slice (${s.feeBps} bps)`);
|
|
4852
|
+
lines.push(` ${import_chalk13.default.dim("fee_recipient:")} ${s.feeRecipient}`);
|
|
4817
4853
|
lines.push("");
|
|
4818
|
-
lines.push(
|
|
4819
|
-
lines.push(
|
|
4854
|
+
lines.push(import_chalk13.default.dim(` New locks will snapshot fee_bps=${s.feeBps} onto themselves.`));
|
|
4855
|
+
lines.push(import_chalk13.default.dim(` Existing locks keep their lock-time snapshot \u2014 no retroactive change.`));
|
|
4820
4856
|
}
|
|
4821
4857
|
return lines.join("\n");
|
|
4822
4858
|
}
|
|
@@ -4841,10 +4877,10 @@ async function runDeriveConditionHash(opts) {
|
|
|
4841
4877
|
}
|
|
4842
4878
|
const api = new ArpApiClient(opts.server);
|
|
4843
4879
|
const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid);
|
|
4844
|
-
progress(opts.json,
|
|
4845
|
-
progress(opts.json,
|
|
4880
|
+
progress(opts.json, import_chalk13.default.dim(`Server: ${api.serverUrl}`));
|
|
4881
|
+
progress(opts.json, import_chalk13.default.dim(`Signer: ${sender.did}`));
|
|
4846
4882
|
const subset = projectDelegationForHash(cmdName, opts, delegationId);
|
|
4847
|
-
const hashBytes = (0,
|
|
4883
|
+
const hashBytes = (0, import_sdk17.deriveDelegationConditionHash)(subset);
|
|
4848
4884
|
const hex = (0, import_utils2.bytesToHex)(hashBytes);
|
|
4849
4885
|
if (opts.json) {
|
|
4850
4886
|
jsonOut({
|
|
@@ -4854,14 +4890,14 @@ async function runDeriveConditionHash(opts) {
|
|
|
4854
4890
|
});
|
|
4855
4891
|
return;
|
|
4856
4892
|
}
|
|
4857
|
-
console.log(
|
|
4858
|
-
console.log(
|
|
4859
|
-
console.log(
|
|
4860
|
-
if (subset.currency !== void 0) console.log(
|
|
4893
|
+
console.log(import_chalk13.default.dim(`Delegation: ${delegationId}`));
|
|
4894
|
+
console.log(import_chalk13.default.dim("Subset hashed:"));
|
|
4895
|
+
console.log(import_chalk13.default.dim(` scopeSummary: ${subset.scopeSummary ?? "(unset)"}`));
|
|
4896
|
+
if (subset.currency !== void 0) console.log(import_chalk13.default.dim(` currency.asset_id: ${subset.currency.asset_id}`));
|
|
4861
4897
|
console.log("");
|
|
4862
|
-
console.log(`${
|
|
4898
|
+
console.log(`${import_chalk13.default.bold("condition_hash:")} ${hex}`);
|
|
4863
4899
|
console.log("");
|
|
4864
|
-
console.log(
|
|
4900
|
+
console.log(import_chalk13.default.dim(`Pass to: heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash ${hex} ...`));
|
|
4865
4901
|
}
|
|
4866
4902
|
function classifyRecoverOutcome(local, server) {
|
|
4867
4903
|
if (local === server) return { kind: "in-sync", value: local };
|
|
@@ -4894,40 +4930,40 @@ async function runRecoverSequence(opts) {
|
|
|
4894
4930
|
applied: opts.apply === true && outcome.kind === "behind"
|
|
4895
4931
|
});
|
|
4896
4932
|
} else {
|
|
4897
|
-
console.log(
|
|
4898
|
-
console.log(
|
|
4933
|
+
console.log(import_chalk13.default.dim(`DID: ${sender.did}`));
|
|
4934
|
+
console.log(import_chalk13.default.dim(`Server: ${api.serverUrl}`));
|
|
4899
4935
|
console.log("");
|
|
4900
|
-
console.log(`${
|
|
4901
|
-
console.log(`${
|
|
4936
|
+
console.log(`${import_chalk13.default.bold("Local lastSenderSequence:")} ${local}`);
|
|
4937
|
+
console.log(`${import_chalk13.default.bold("Server lastSenderSequence:")} ${server}`);
|
|
4902
4938
|
console.log("");
|
|
4903
4939
|
if (outcome.kind === "in-sync") {
|
|
4904
|
-
console.log(
|
|
4940
|
+
console.log(import_chalk13.default.green("\u2713 In sync \u2014 no recovery needed."));
|
|
4905
4941
|
} else if (outcome.kind === "behind") {
|
|
4906
|
-
console.log(
|
|
4942
|
+
console.log(import_chalk13.default.yellow(`\u26A0 Local is BEHIND by ${outcome.drift}. Server has accepted envelopes the CLI didn't classify as post-commit.`));
|
|
4907
4943
|
if (opts.apply) {
|
|
4908
|
-
console.log(
|
|
4944
|
+
console.log(import_chalk13.default.dim("Writing server value to local state..."));
|
|
4909
4945
|
} else {
|
|
4910
|
-
console.log(
|
|
4946
|
+
console.log(import_chalk13.default.dim("Dry-run. Pass --apply to update local state to match server."));
|
|
4911
4947
|
}
|
|
4912
4948
|
} else {
|
|
4913
|
-
console.log(
|
|
4914
|
-
console.log(
|
|
4915
|
-
console.log(
|
|
4916
|
-
console.log(
|
|
4917
|
-
console.log(
|
|
4949
|
+
console.log(import_chalk13.default.red(`\u2717 Local is AHEAD of server by ${outcome.drift}. This should not happen under normal protocol flow.`));
|
|
4950
|
+
console.log(import_chalk13.default.dim("NOT applying \u2014 manual investigation needed. Possible causes:"));
|
|
4951
|
+
console.log(import_chalk13.default.dim(" - Local agents.json edited by hand to a wrong value"));
|
|
4952
|
+
console.log(import_chalk13.default.dim(" - Server data lost / rolled back"));
|
|
4953
|
+
console.log(import_chalk13.default.dim(" - HEYARP_HOME pointed at a wrong account"));
|
|
4918
4954
|
}
|
|
4919
4955
|
}
|
|
4920
4956
|
if (outcome.kind === "behind" && opts.apply) {
|
|
4921
4957
|
updateAgentLocal(opts.server, sender.did, { lastSenderSequence: outcome.server });
|
|
4922
|
-
if (!opts.json) console.log(
|
|
4958
|
+
if (!opts.json) console.log(import_chalk13.default.green(`\u2713 Local lastSenderSequence updated: ${local} \u2192 ${outcome.server}`));
|
|
4923
4959
|
}
|
|
4924
4960
|
if (outcome.kind === "behind" && !opts.apply) process.exitCode = 1;
|
|
4925
4961
|
if (outcome.kind === "ahead") process.exitCode = 2;
|
|
4926
4962
|
}
|
|
4927
4963
|
|
|
4928
4964
|
// src/commands/events.ts
|
|
4929
|
-
var
|
|
4930
|
-
var
|
|
4965
|
+
var import_sdk18 = require("@heyanon-arp/sdk");
|
|
4966
|
+
var import_chalk14 = __toESM(require("chalk"));
|
|
4931
4967
|
init_api();
|
|
4932
4968
|
function registerEventsCommand(root) {
|
|
4933
4969
|
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(
|
|
@@ -4971,14 +5007,14 @@ async function runEvents(relationshipId, opts) {
|
|
|
4971
5007
|
const api = new ArpApiClient(opts.server);
|
|
4972
5008
|
const sender = resolveSenderAgent("events", opts.server, opts.fromDid);
|
|
4973
5009
|
if (!opts.json) {
|
|
4974
|
-
console.log(
|
|
4975
|
-
console.log(
|
|
4976
|
-
console.log(
|
|
5010
|
+
console.log(import_chalk14.default.dim(`Server: ${api.serverUrl}`));
|
|
5011
|
+
console.log(import_chalk14.default.dim(`Signer: ${sender.did}`));
|
|
5012
|
+
console.log(import_chalk14.default.dim(`Relationship: ${relationshipId}`));
|
|
4977
5013
|
}
|
|
4978
5014
|
const query = { limit };
|
|
4979
5015
|
if (since !== void 0) query.since = since;
|
|
4980
|
-
if (opts.successOnly) query.readModelStatus =
|
|
4981
|
-
else if (opts.rejectedOnly) query.readModelStatus =
|
|
5016
|
+
if (opts.successOnly) query.readModelStatus = import_sdk18.ReadModelStatuses.MATERIALIZED;
|
|
5017
|
+
else if (opts.rejectedOnly) query.readModelStatus = import_sdk18.ReadModelStatuses.REJECTED;
|
|
4982
5018
|
const signer = makeSigner(sender);
|
|
4983
5019
|
const events = await api.listEvents(relationshipId, signer, query);
|
|
4984
5020
|
if (opts.json) {
|
|
@@ -4986,7 +5022,7 @@ async function runEvents(relationshipId, opts) {
|
|
|
4986
5022
|
return;
|
|
4987
5023
|
}
|
|
4988
5024
|
if (events.length === 0) {
|
|
4989
|
-
console.log(
|
|
5025
|
+
console.log(import_chalk14.default.dim("\n(no events for this relationship)"));
|
|
4990
5026
|
return;
|
|
4991
5027
|
}
|
|
4992
5028
|
console.log("");
|
|
@@ -5002,20 +5038,20 @@ async function runEvents(relationshipId, opts) {
|
|
|
5002
5038
|
}));
|
|
5003
5039
|
}
|
|
5004
5040
|
const lastIndex = events[events.length - 1].relationshipEventIndex;
|
|
5005
|
-
console.log(
|
|
5041
|
+
console.log(import_chalk14.default.dim(`
|
|
5006
5042
|
${events.length} event(s). Paginate with --since ${lastIndex + 1}.`));
|
|
5007
5043
|
}
|
|
5008
5044
|
function formatEventLine(ev, selfDid, opts = {}) {
|
|
5009
|
-
const idx =
|
|
5045
|
+
const idx = import_chalk14.default.bold(`#${ev.relationshipEventIndex}`);
|
|
5010
5046
|
const eventId = opts.fullIds ? ev.eventId : eventIdHead(ev.eventId);
|
|
5011
5047
|
const type = ev.type.padEnd(20);
|
|
5012
5048
|
const direction = directionLabel(ev, selfDid, opts);
|
|
5013
5049
|
const hash = opts.fullIds ? ev.serverEventHash : hashHead(ev.serverEventHash);
|
|
5014
5050
|
const extra = extraDetail(ev);
|
|
5015
|
-
const tail = extra ? ` ${
|
|
5016
|
-
const status = ev.readModelStatus ??
|
|
5017
|
-
const statusGlyph = status ===
|
|
5018
|
-
return `${statusGlyph}${idx} ${
|
|
5051
|
+
const tail = extra ? ` ${import_chalk14.default.dim(`(${extra})`)}` : "";
|
|
5052
|
+
const status = ev.readModelStatus ?? import_sdk18.ReadModelStatuses.MATERIALIZED;
|
|
5053
|
+
const statusGlyph = status === import_sdk18.ReadModelStatuses.REJECTED ? `${import_chalk14.default.red("\u2717")} ` : " ";
|
|
5054
|
+
return `${statusGlyph}${idx} ${import_chalk14.default.cyan(eventId)} ${type} ${direction} ${import_chalk14.default.cyan(hash)}${tail}`;
|
|
5019
5055
|
}
|
|
5020
5056
|
function eventIdHead(eventId) {
|
|
5021
5057
|
if (eventId.length <= 20) return eventId;
|
|
@@ -5024,9 +5060,9 @@ function eventIdHead(eventId) {
|
|
|
5024
5060
|
function directionLabel(ev, selfDid, opts = {}) {
|
|
5025
5061
|
const senderHead = opts.fullIds ? ev.senderDid : didHead2(ev.senderDid);
|
|
5026
5062
|
const recipientHead = opts.fullIds ? ev.recipientDid : didHead2(ev.recipientDid);
|
|
5027
|
-
if (ev.senderDid === selfDid) return `${
|
|
5028
|
-
if (ev.recipientDid === selfDid) return `${
|
|
5029
|
-
return `${
|
|
5063
|
+
if (ev.senderDid === selfDid) return `${import_chalk14.default.bold("me")} \u2192 ${import_chalk14.default.dim(recipientHead)}`;
|
|
5064
|
+
if (ev.recipientDid === selfDid) return `${import_chalk14.default.dim(senderHead)} \u2192 ${import_chalk14.default.bold("me")}`;
|
|
5065
|
+
return `${import_chalk14.default.dim(senderHead)} \u2192 ${import_chalk14.default.dim(recipientHead)}`;
|
|
5030
5066
|
}
|
|
5031
5067
|
function extraDetail(ev) {
|
|
5032
5068
|
if (ev.type === "handshake_response") {
|
|
@@ -5063,7 +5099,7 @@ function parseSince(raw) {
|
|
|
5063
5099
|
}
|
|
5064
5100
|
|
|
5065
5101
|
// src/commands/guide.ts
|
|
5066
|
-
var
|
|
5102
|
+
var import_chalk15 = __toESM(require("chalk"));
|
|
5067
5103
|
|
|
5068
5104
|
// src/guide/source.ts
|
|
5069
5105
|
var GUIDE_TITLE = "HeyARP CLI \u2014 agent guide";
|
|
@@ -5597,7 +5633,7 @@ var GUIDE_SECTIONS = [
|
|
|
5597
5633
|
" 1. heyarp login link this CLI to your Solana wallet \u2014 hand the",
|
|
5598
5634
|
" printed URL to your HUMAN operator (browser",
|
|
5599
5635
|
" approval; registration REQUIRES it)",
|
|
5600
|
-
" 2. heyarp register
|
|
5636
|
+
" 2. heyarp register --name <handle> create your DID + Ed25519 keys (handle: unique, lowercase a-z0-9_ 3-32, immutable \u2014 others can address you by it instead of your DID, e.g. `send-handshake <handle>`; `heyarp whois <handle>` resolves it)",
|
|
5601
5637
|
" 3. heyarp whoami confirm your DID + login account are set",
|
|
5602
5638
|
" 4. role for THIS deal: you SEND the offer \u2192 buyer; an offer ARRIVES \u2192 worker",
|
|
5603
5639
|
" 5. BUYER only \u2014 fund your settlement wallet: `whoami --local` \u2192",
|
|
@@ -5704,7 +5740,7 @@ function renderCommand(c) {
|
|
|
5704
5740
|
${c.description}`;
|
|
5705
5741
|
}
|
|
5706
5742
|
function renderSection(s) {
|
|
5707
|
-
const lines = [
|
|
5743
|
+
const lines = [import_chalk15.default.bold(s.title)];
|
|
5708
5744
|
if (s.body && s.body.length > 0) lines.push(...s.body);
|
|
5709
5745
|
if (s.nextActions && s.nextActions.length > 0) {
|
|
5710
5746
|
lines.push(" Commands:");
|
|
@@ -5731,21 +5767,21 @@ function modeHeader(mode) {
|
|
|
5731
5767
|
""
|
|
5732
5768
|
];
|
|
5733
5769
|
case "role":
|
|
5734
|
-
return [
|
|
5770
|
+
return [import_chalk15.default.dim(`(${mode.role} guide \u2014 your slice only; run \`heyarp guide\` for the overview)`), ""];
|
|
5735
5771
|
case "setup":
|
|
5736
|
-
return [
|
|
5772
|
+
return [import_chalk15.default.dim("(setup \u2014 role-agnostic; run `heyarp guide` for the overview)"), ""];
|
|
5737
5773
|
case "troubleshoot":
|
|
5738
|
-
return [
|
|
5774
|
+
return [import_chalk15.default.dim("(troubleshooting \u2014 role-agnostic)"), ""];
|
|
5739
5775
|
}
|
|
5740
5776
|
}
|
|
5741
5777
|
function modeFooter(mode) {
|
|
5742
5778
|
if (mode.kind === "overview") {
|
|
5743
|
-
return ["",
|
|
5779
|
+
return ["", import_chalk15.default.dim("Full reference per role: `heyarp guide --role worker|buyer`. Docs: https://www.npmjs.com/package/@heyanon-arp/cli")];
|
|
5744
5780
|
}
|
|
5745
5781
|
return [];
|
|
5746
5782
|
}
|
|
5747
5783
|
function renderGuide(mode = { kind: "overview" }) {
|
|
5748
|
-
const blocks = [
|
|
5784
|
+
const blocks = [import_chalk15.default.bold(GUIDE_TITLE), "", ...modeHeader(mode)];
|
|
5749
5785
|
for (const s of selectSections(mode)) {
|
|
5750
5786
|
blocks.push(renderSection(s), "");
|
|
5751
5787
|
}
|
|
@@ -5795,7 +5831,7 @@ function renderPrompt(mode, opts = { concise: false }) {
|
|
|
5795
5831
|
// src/commands/homes.ts
|
|
5796
5832
|
var import_node_fs6 = require("fs");
|
|
5797
5833
|
var import_node_path6 = require("path");
|
|
5798
|
-
var
|
|
5834
|
+
var import_chalk16 = __toESM(require("chalk"));
|
|
5799
5835
|
var import_prompts = __toESM(require("prompts"));
|
|
5800
5836
|
|
|
5801
5837
|
// src/homes.ts
|
|
@@ -5889,27 +5925,27 @@ function runHomes(opts) {
|
|
|
5889
5925
|
return;
|
|
5890
5926
|
}
|
|
5891
5927
|
if (rows.length === 0) {
|
|
5892
|
-
console.log(
|
|
5893
|
-
console.log(
|
|
5928
|
+
console.log(import_chalk16.default.dim("(no HEYARP_HOME directories registered yet \u2014 run `heyarp register` once and the registry populates itself)"));
|
|
5929
|
+
console.log(import_chalk16.default.dim(` registry path: ${homesRegistryPath()}`));
|
|
5894
5930
|
return;
|
|
5895
5931
|
}
|
|
5896
5932
|
const header = ["Path", "Agents", "Last seen", "Status"];
|
|
5897
5933
|
const data = rows.map((r) => [
|
|
5898
|
-
r.path + (r.isCurrent ?
|
|
5934
|
+
r.path + (r.isCurrent ? import_chalk16.default.green(" (current)") : ""),
|
|
5899
5935
|
String(r.agentCount),
|
|
5900
5936
|
formatRelativeTime(r.lastSeenAt),
|
|
5901
|
-
r.exists ?
|
|
5937
|
+
r.exists ? import_chalk16.default.green("ok") : import_chalk16.default.red("missing")
|
|
5902
5938
|
]);
|
|
5903
5939
|
console.log("");
|
|
5904
5940
|
console.log(formatTable(header, data));
|
|
5905
|
-
console.log(
|
|
5941
|
+
console.log(import_chalk16.default.dim(`
|
|
5906
5942
|
Registry path: ${homesRegistryPath()}`));
|
|
5907
|
-
console.log(
|
|
5943
|
+
console.log(import_chalk16.default.dim(`Set HEYARP_HOME=<path> in a shell to switch between homes; run \`heyarp homes forget <path>\` to drop a stale entry.`));
|
|
5908
5944
|
}
|
|
5909
5945
|
async function runForget(path, opts) {
|
|
5910
5946
|
if (!opts.yes) {
|
|
5911
|
-
console.log(
|
|
5912
|
-
console.log(
|
|
5947
|
+
console.log(import_chalk16.default.yellow(`About to remove '${path}' from the homes registry.`));
|
|
5948
|
+
console.log(import_chalk16.default.dim(" Note: this only forgets the registry entry; the directory + its agents.json are NOT touched."));
|
|
5913
5949
|
const answer = await (0, import_prompts.default)(
|
|
5914
5950
|
{
|
|
5915
5951
|
type: "confirm",
|
|
@@ -5919,21 +5955,21 @@ async function runForget(path, opts) {
|
|
|
5919
5955
|
},
|
|
5920
5956
|
{
|
|
5921
5957
|
onCancel: () => {
|
|
5922
|
-
console.log(
|
|
5958
|
+
console.log(import_chalk16.default.yellow("Aborted."));
|
|
5923
5959
|
process.exit(130);
|
|
5924
5960
|
}
|
|
5925
5961
|
}
|
|
5926
5962
|
);
|
|
5927
5963
|
if (!answer.confirm) {
|
|
5928
|
-
console.log(
|
|
5964
|
+
console.log(import_chalk16.default.dim("Aborted (no changes)."));
|
|
5929
5965
|
return;
|
|
5930
5966
|
}
|
|
5931
5967
|
}
|
|
5932
5968
|
const removed = forgetHome(path);
|
|
5933
5969
|
if (removed) {
|
|
5934
|
-
console.log(
|
|
5970
|
+
console.log(import_chalk16.default.green(`\u2713 forgot ${path}`));
|
|
5935
5971
|
} else {
|
|
5936
|
-
console.log(
|
|
5972
|
+
console.log(import_chalk16.default.dim(`(no entry for ${path} in the registry \u2014 already absent)`));
|
|
5937
5973
|
}
|
|
5938
5974
|
}
|
|
5939
5975
|
function countAgents(homePath) {
|
|
@@ -5958,13 +5994,13 @@ function formatTable(header, data) {
|
|
|
5958
5994
|
const padding = " ".repeat(Math.max(0, widths[i] - lengths[i]));
|
|
5959
5995
|
return cell + padding;
|
|
5960
5996
|
}).join(" ");
|
|
5961
|
-
const headerLine =
|
|
5997
|
+
const headerLine = import_chalk16.default.bold(
|
|
5962
5998
|
pad(
|
|
5963
5999
|
header,
|
|
5964
6000
|
header.map((s) => s.length)
|
|
5965
6001
|
)
|
|
5966
6002
|
);
|
|
5967
|
-
const sepLine =
|
|
6003
|
+
const sepLine = import_chalk16.default.dim(
|
|
5968
6004
|
pad(
|
|
5969
6005
|
widths.map((w) => "-".repeat(w)),
|
|
5970
6006
|
widths
|
|
@@ -5991,7 +6027,7 @@ function formatRelativeTime(iso) {
|
|
|
5991
6027
|
}
|
|
5992
6028
|
|
|
5993
6029
|
// src/commands/inbox.ts
|
|
5994
|
-
var
|
|
6030
|
+
var import_chalk17 = __toESM(require("chalk"));
|
|
5995
6031
|
init_api();
|
|
5996
6032
|
function formatTailStartedPing(input) {
|
|
5997
6033
|
const ping = {
|
|
@@ -6038,8 +6074,8 @@ async function runInbox(positionalDid, opts) {
|
|
|
6038
6074
|
}
|
|
6039
6075
|
const api = new ArpApiClient(opts.server);
|
|
6040
6076
|
if (!opts.json) {
|
|
6041
|
-
console.log(
|
|
6042
|
-
console.log(
|
|
6077
|
+
console.log(import_chalk17.default.dim(`Server: ${api.serverUrl}`));
|
|
6078
|
+
console.log(import_chalk17.default.dim(`Signer: ${local.did}`));
|
|
6043
6079
|
}
|
|
6044
6080
|
const query = { limit };
|
|
6045
6081
|
if (opts.before) query.before = opts.before;
|
|
@@ -6053,7 +6089,7 @@ async function runInbox(positionalDid, opts) {
|
|
|
6053
6089
|
return;
|
|
6054
6090
|
}
|
|
6055
6091
|
if (events.length === 0) {
|
|
6056
|
-
console.log(
|
|
6092
|
+
console.log(import_chalk17.default.dim("\n(no events addressed to me \u2014 `heyarp events <relationship-id>` shows the chain-wide listing)"));
|
|
6057
6093
|
return;
|
|
6058
6094
|
}
|
|
6059
6095
|
console.log("");
|
|
@@ -6068,16 +6104,16 @@ async function runInbox(positionalDid, opts) {
|
|
|
6068
6104
|
secondary: `eventId=${ev.eventId} serverEventHash=${ev.serverEventHash}`
|
|
6069
6105
|
}));
|
|
6070
6106
|
}
|
|
6071
|
-
const addressedToMeHint =
|
|
6107
|
+
const addressedToMeHint = import_chalk17.default.dim(" (envelopes addressed to me \u2014 for the full chain see `heyarp events <relationship-id>`)");
|
|
6072
6108
|
if (opts.since && !opts.before) {
|
|
6073
6109
|
console.log(
|
|
6074
|
-
|
|
6110
|
+
import_chalk17.default.dim(
|
|
6075
6111
|
`
|
|
6076
6112
|
${events.length} event(s) (oldest-first).${addressedToMeHint} Advance the forward cursor with --since <serverTimestamp> --since-event-id <eventId> using the LAST row above.`
|
|
6077
6113
|
)
|
|
6078
6114
|
);
|
|
6079
6115
|
} else {
|
|
6080
|
-
console.log(
|
|
6116
|
+
console.log(import_chalk17.default.dim(`
|
|
6081
6117
|
${events.length} event(s).${addressedToMeHint} Paginate with --before <serverTimestamp> --before-event-id <eventId> using the LAST row above.`));
|
|
6082
6118
|
}
|
|
6083
6119
|
}
|
|
@@ -6092,7 +6128,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
6092
6128
|
} else {
|
|
6093
6129
|
warn(
|
|
6094
6130
|
opts.json,
|
|
6095
|
-
|
|
6131
|
+
import_chalk17.default.yellow(
|
|
6096
6132
|
"\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."
|
|
6097
6133
|
)
|
|
6098
6134
|
);
|
|
@@ -6102,9 +6138,9 @@ async function runInboxTail(did, local, opts) {
|
|
|
6102
6138
|
if (opts.json) {
|
|
6103
6139
|
console.log(formatTailStartedPing({ server: api.serverUrl, signer: local.did, stdoutBlockingApplied }));
|
|
6104
6140
|
} else {
|
|
6105
|
-
console.log(
|
|
6106
|
-
console.log(
|
|
6107
|
-
console.log(
|
|
6141
|
+
console.log(import_chalk17.default.dim(`Server: ${api.serverUrl}`));
|
|
6142
|
+
console.log(import_chalk17.default.dim(`Signer: ${local.did}`));
|
|
6143
|
+
console.log(import_chalk17.default.dim("Mode: --tail (live SSE, Ctrl-C to stop)"));
|
|
6108
6144
|
}
|
|
6109
6145
|
const controller = new AbortController();
|
|
6110
6146
|
let userAborted = false;
|
|
@@ -6123,7 +6159,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
6123
6159
|
}
|
|
6124
6160
|
if (event.type === "heartbeat") continue;
|
|
6125
6161
|
if (event.type === "connected") {
|
|
6126
|
-
console.log(
|
|
6162
|
+
console.log(import_chalk17.default.green("\u25CF stream open \u2014 listening for envelopes..."));
|
|
6127
6163
|
continue;
|
|
6128
6164
|
}
|
|
6129
6165
|
if (event.type === "envelope") {
|
|
@@ -6137,7 +6173,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
6137
6173
|
}
|
|
6138
6174
|
continue;
|
|
6139
6175
|
}
|
|
6140
|
-
console.log(
|
|
6176
|
+
console.log(import_chalk17.default.dim(`(unknown event: ${event.type})`));
|
|
6141
6177
|
}
|
|
6142
6178
|
if (!userAborted) {
|
|
6143
6179
|
throw new Error("inbox --tail: stream ended unexpectedly (server may have restarted, or change stream errored). Re-run to reconnect.");
|
|
@@ -6145,7 +6181,7 @@ async function runInboxTail(did, local, opts) {
|
|
|
6145
6181
|
} catch (err) {
|
|
6146
6182
|
const name = err.name;
|
|
6147
6183
|
if (name === "AbortError" || userAborted) {
|
|
6148
|
-
if (!opts.json) console.log(
|
|
6184
|
+
if (!opts.json) console.log(import_chalk17.default.dim("\nstream closed."));
|
|
6149
6185
|
return;
|
|
6150
6186
|
}
|
|
6151
6187
|
throw err;
|
|
@@ -6165,15 +6201,15 @@ function formatInboxTable(events, opts = {}) {
|
|
|
6165
6201
|
]);
|
|
6166
6202
|
const widths = header.map((h, i) => Math.max(h.length, ...data.map((row) => row[i].length)));
|
|
6167
6203
|
const pad = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
6168
|
-
const lines = [
|
|
6169
|
-
const detail = events.map((ev) => ` ${
|
|
6204
|
+
const lines = [import_chalk17.default.bold(pad(header)), import_chalk17.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))];
|
|
6205
|
+
const detail = events.map((ev) => ` ${import_chalk17.default.dim("eventId:")} ${import_chalk17.default.cyan(ev.eventId)} ${import_chalk17.default.dim("serverTimestamp:")} ${import_chalk17.default.cyan(ev.serverTimestamp)}`).join("\n");
|
|
6170
6206
|
return `${lines.join("\n")}
|
|
6171
6207
|
|
|
6172
|
-
${
|
|
6208
|
+
${import_chalk17.default.bold("Pagination cursors")} (last \u2192 first):
|
|
6173
6209
|
${detail}`;
|
|
6174
6210
|
}
|
|
6175
6211
|
function hashHead2(hash) {
|
|
6176
|
-
if (!hash) return
|
|
6212
|
+
if (!hash) return import_chalk17.default.dim("(none)");
|
|
6177
6213
|
if (hash.length <= 14) return hash;
|
|
6178
6214
|
return `${hash.slice(0, 14)}...`;
|
|
6179
6215
|
}
|
|
@@ -6189,8 +6225,8 @@ function parseLimit4(raw) {
|
|
|
6189
6225
|
// src/commands/keys.ts
|
|
6190
6226
|
var import_node_crypto2 = require("crypto");
|
|
6191
6227
|
var import_node_fs7 = require("fs");
|
|
6192
|
-
var
|
|
6193
|
-
var
|
|
6228
|
+
var import_sdk19 = require("@heyanon-arp/sdk");
|
|
6229
|
+
var import_chalk18 = __toESM(require("chalk"));
|
|
6194
6230
|
function writeSecretFile(path, body) {
|
|
6195
6231
|
const tmp = `${path}.tmp.${(0, import_node_crypto2.randomBytes)(8).toString("hex")}`;
|
|
6196
6232
|
const fd = (0, import_node_fs7.openSync)(tmp, "wx", 384);
|
|
@@ -6217,19 +6253,19 @@ function writeSecretFile(path, body) {
|
|
|
6217
6253
|
function registerKeysCommand(root) {
|
|
6218
6254
|
const keys = root.command("keys").description("Local key utilities");
|
|
6219
6255
|
keys.command("gen").description("Generate a fresh identity + settlement keypair (no save by default)").action(() => {
|
|
6220
|
-
const identity = (0,
|
|
6221
|
-
const settlement = (0,
|
|
6256
|
+
const identity = (0, import_sdk19.generateKeyPair)();
|
|
6257
|
+
const settlement = (0, import_sdk19.generateKeyPair)();
|
|
6222
6258
|
const out = [
|
|
6223
|
-
|
|
6224
|
-
` public (base58btc): ${
|
|
6225
|
-
` secret (base64) : ${
|
|
6259
|
+
import_chalk18.default.bold("Identity key (Ed25519)"),
|
|
6260
|
+
` public (base58btc): ${import_chalk18.default.cyan((0, import_sdk19.base58btcEncode)(identity.publicKey))}`,
|
|
6261
|
+
` secret (base64) : ${import_chalk18.default.yellow(Buffer.from(identity.secretKey).toString("base64"))}`,
|
|
6226
6262
|
"",
|
|
6227
|
-
|
|
6228
|
-
` public (base58btc): ${
|
|
6229
|
-
` secret (base64) : ${
|
|
6263
|
+
import_chalk18.default.bold("Settlement key (Ed25519)"),
|
|
6264
|
+
` public (base58btc): ${import_chalk18.default.cyan((0, import_sdk19.base58btcEncode)(settlement.publicKey))}`,
|
|
6265
|
+
` secret (base64) : ${import_chalk18.default.yellow(Buffer.from(settlement.secretKey).toString("base64"))}`,
|
|
6230
6266
|
"",
|
|
6231
|
-
|
|
6232
|
-
` ${
|
|
6267
|
+
import_chalk18.default.bold("Resulting DID"),
|
|
6268
|
+
` ${import_chalk18.default.cyan((0, import_sdk19.formatDid)(identity.publicKey))}`
|
|
6233
6269
|
];
|
|
6234
6270
|
console.log(out.join("\n"));
|
|
6235
6271
|
});
|
|
@@ -6238,20 +6274,20 @@ function registerKeysCommand(root) {
|
|
|
6238
6274
|
const json = JSON.stringify(toKeyBundle(agent, (/* @__PURE__ */ new Date()).toISOString()), null, 2);
|
|
6239
6275
|
if (opts.out) {
|
|
6240
6276
|
writeSecretFile(opts.out, json);
|
|
6241
|
-
process.stderr.write(
|
|
6277
|
+
process.stderr.write(import_chalk18.default.yellow(`\u26A0 wrote SECRET key bundle to ${opts.out} (mode 0600) \u2014 keep it offline; anyone with this file can operate ${did}.
|
|
6242
6278
|
`));
|
|
6243
6279
|
console.log(opts.out);
|
|
6244
6280
|
} else {
|
|
6245
|
-
process.stderr.write(
|
|
6281
|
+
process.stderr.write(import_chalk18.default.yellow("\u26A0 this is a SECRET key bundle \u2014 redirect to a file and keep it offline.\n"));
|
|
6246
6282
|
console.log(json);
|
|
6247
6283
|
}
|
|
6248
6284
|
});
|
|
6249
6285
|
keys.command("whoami").description("Print the DID derived from a base64-encoded identity secret key").argument("<secret-key-b64>", "32-byte Ed25519 seed, base64").action((secretKeyB64) => {
|
|
6250
6286
|
const seed = decodeSeed(secretKeyB64);
|
|
6251
|
-
const pub = (0,
|
|
6252
|
-
const did = (0,
|
|
6253
|
-
console.log(`${
|
|
6254
|
-
console.log(`${
|
|
6287
|
+
const pub = (0, import_sdk19.getPublicKey)(seed);
|
|
6288
|
+
const did = (0, import_sdk19.formatDid)(pub);
|
|
6289
|
+
console.log(`${import_chalk18.default.bold("DID")}: ${import_chalk18.default.cyan(did)}`);
|
|
6290
|
+
console.log(`${import_chalk18.default.bold("Identity public key (base58btc)")}: ${import_chalk18.default.cyan((0, import_sdk19.base58btcEncode)(pub))}`);
|
|
6255
6291
|
});
|
|
6256
6292
|
}
|
|
6257
6293
|
function decodeSeed(b64) {
|
|
@@ -6268,7 +6304,7 @@ function decodeSeed(b64) {
|
|
|
6268
6304
|
}
|
|
6269
6305
|
|
|
6270
6306
|
// src/commands/list.ts
|
|
6271
|
-
var
|
|
6307
|
+
var import_chalk19 = __toESM(require("chalk"));
|
|
6272
6308
|
function registerListCommand(root) {
|
|
6273
6309
|
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) => {
|
|
6274
6310
|
const rows = listAgents();
|
|
@@ -6277,7 +6313,7 @@ function registerListCommand(root) {
|
|
|
6277
6313
|
return;
|
|
6278
6314
|
}
|
|
6279
6315
|
if (rows.length === 0) {
|
|
6280
|
-
console.log(
|
|
6316
|
+
console.log(import_chalk19.default.dim(`No local agents. State file: ${stateFilePath()}`));
|
|
6281
6317
|
return;
|
|
6282
6318
|
}
|
|
6283
6319
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -6289,7 +6325,7 @@ function registerListCommand(root) {
|
|
|
6289
6325
|
for (const [serverUrl, group] of grouped) {
|
|
6290
6326
|
if (!first) console.log("");
|
|
6291
6327
|
first = false;
|
|
6292
|
-
console.log(
|
|
6328
|
+
console.log(import_chalk19.default.bold(`Server: ${serverUrl}`));
|
|
6293
6329
|
console.log(formatAgentsTable(group.map(({ agent }) => ({ did: agent.did, name: agent.name, tags: agent.tags, registeredAt: agent.registeredAt }))));
|
|
6294
6330
|
}
|
|
6295
6331
|
});
|
|
@@ -6297,7 +6333,7 @@ function registerListCommand(root) {
|
|
|
6297
6333
|
|
|
6298
6334
|
// src/commands/login.ts
|
|
6299
6335
|
var import_node_crypto3 = require("crypto");
|
|
6300
|
-
var
|
|
6336
|
+
var import_chalk20 = __toESM(require("chalk"));
|
|
6301
6337
|
init_api();
|
|
6302
6338
|
var POLL_INTERVAL_MS = 2e3;
|
|
6303
6339
|
var POLL_TIMEOUT_MS = 11 * 6e4;
|
|
@@ -6367,9 +6403,9 @@ function registerLoginCommand(root) {
|
|
|
6367
6403
|
jsonOut({ serverUrl: result.serverUrl, wallet: result.wallet, credentialsPath: credentialsFilePath() });
|
|
6368
6404
|
} else {
|
|
6369
6405
|
console.log("");
|
|
6370
|
-
console.log(`${
|
|
6371
|
-
console.log(
|
|
6372
|
-
console.log(
|
|
6406
|
+
console.log(`${import_chalk20.default.green("Logged in as")} ${import_chalk20.default.cyan(result.wallet)}`);
|
|
6407
|
+
console.log(import_chalk20.default.dim(`If that is not the wallet you approved with, run heyarp logout immediately.`));
|
|
6408
|
+
console.log(import_chalk20.default.dim(`Credential saved to ${credentialsFilePath()} (mode 0600).`));
|
|
6373
6409
|
}
|
|
6374
6410
|
} catch (err) {
|
|
6375
6411
|
emitActionError(err, cmd);
|
|
@@ -6379,7 +6415,7 @@ function registerLoginCommand(root) {
|
|
|
6379
6415
|
}
|
|
6380
6416
|
|
|
6381
6417
|
// src/commands/logout.ts
|
|
6382
|
-
var
|
|
6418
|
+
var import_chalk21 = __toESM(require("chalk"));
|
|
6383
6419
|
init_api();
|
|
6384
6420
|
function registerLogoutCommand(root) {
|
|
6385
6421
|
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) => {
|
|
@@ -6404,7 +6440,7 @@ function registerLogoutCommand(root) {
|
|
|
6404
6440
|
if (opts.json) {
|
|
6405
6441
|
jsonOut({ serverUrl: api.serverUrl, loggedOut: true, wallet: credential.wallet });
|
|
6406
6442
|
} else {
|
|
6407
|
-
console.log(`${
|
|
6443
|
+
console.log(`${import_chalk21.default.green("Logged out of")} ${api.serverUrl} ${import_chalk21.default.dim(`(was ${credential.wallet})`)}`);
|
|
6408
6444
|
}
|
|
6409
6445
|
} catch (err) {
|
|
6410
6446
|
emitActionError(err, cmd);
|
|
@@ -6413,13 +6449,65 @@ function registerLogoutCommand(root) {
|
|
|
6413
6449
|
});
|
|
6414
6450
|
}
|
|
6415
6451
|
|
|
6452
|
+
// src/commands/name.ts
|
|
6453
|
+
var import_sdk20 = require("@heyanon-arp/sdk");
|
|
6454
|
+
var import_chalk22 = __toESM(require("chalk"));
|
|
6455
|
+
init_api();
|
|
6456
|
+
function registerNameCommand(root) {
|
|
6457
|
+
const name = root.command("name").description("Agent name (handle) utilities.");
|
|
6458
|
+
name.command("check").description("Check whether an agent name (handle) can be registered \u2014 reports invalid / reserved / taken / available without registering.").argument("<name>", "Candidate handle (lowercase a-z0-9_, 3-32 chars)").option("--server <url>", "Override ARP server base URL").option("--json", "Emit {name, available, reason, did?} as a single JSON object on stdout.", false).action(async (input, opts) => {
|
|
6459
|
+
const result = await runNameCheck(input, opts);
|
|
6460
|
+
if (opts.json) {
|
|
6461
|
+
jsonOut(result);
|
|
6462
|
+
} else {
|
|
6463
|
+
printNameCheck(input, result);
|
|
6464
|
+
}
|
|
6465
|
+
if (!result.available) process.exitCode = 1;
|
|
6466
|
+
});
|
|
6467
|
+
}
|
|
6468
|
+
async function runNameCheck(input, opts) {
|
|
6469
|
+
const name = (0, import_sdk20.normalizeName)(input);
|
|
6470
|
+
if (!(0, import_sdk20.isValidAgentName)(name)) {
|
|
6471
|
+
return { name, available: false, reason: "invalid" };
|
|
6472
|
+
}
|
|
6473
|
+
if ((0, import_sdk20.isReservedName)(name)) {
|
|
6474
|
+
return { name, available: false, reason: "reserved" };
|
|
6475
|
+
}
|
|
6476
|
+
const api = new ArpApiClient(opts.server);
|
|
6477
|
+
progress(opts.json, import_chalk22.default.dim(`Server: ${api.serverUrl}`));
|
|
6478
|
+
try {
|
|
6479
|
+
const profile = await api.discoverByName(name);
|
|
6480
|
+
return { name, available: false, reason: "taken", did: profile.did };
|
|
6481
|
+
} catch (err) {
|
|
6482
|
+
if (err instanceof ApiError && err.payload.code === "AGENT_NOT_FOUND") {
|
|
6483
|
+
return { name, available: true, reason: null };
|
|
6484
|
+
}
|
|
6485
|
+
throw err;
|
|
6486
|
+
}
|
|
6487
|
+
}
|
|
6488
|
+
function printNameCheck(input, r) {
|
|
6489
|
+
switch (r.reason) {
|
|
6490
|
+
case "invalid":
|
|
6491
|
+
console.log(`${import_chalk22.default.red("\u2717")} '${input}' is not a valid handle \u2014 must be lowercase a-z0-9_, 3-32 chars.`);
|
|
6492
|
+
break;
|
|
6493
|
+
case "reserved":
|
|
6494
|
+
console.log(`${import_chalk22.default.red("\u2717")} '${r.name}' is reserved and cannot be registered.`);
|
|
6495
|
+
break;
|
|
6496
|
+
case "taken":
|
|
6497
|
+
console.log(`${import_chalk22.default.yellow("\u2717")} '${r.name}' is taken \u2192 ${import_chalk22.default.cyan(r.did ?? "(unknown DID)")}`);
|
|
6498
|
+
break;
|
|
6499
|
+
default:
|
|
6500
|
+
console.log(`${import_chalk22.default.green("\u2713")} '${r.name}' is available.`);
|
|
6501
|
+
}
|
|
6502
|
+
}
|
|
6503
|
+
|
|
6416
6504
|
// src/commands/profile.ts
|
|
6417
|
-
var
|
|
6418
|
-
var
|
|
6505
|
+
var import_sdk21 = require("@heyanon-arp/sdk");
|
|
6506
|
+
var import_chalk23 = __toESM(require("chalk"));
|
|
6419
6507
|
init_api();
|
|
6420
6508
|
function registerProfileCommand(root) {
|
|
6421
6509
|
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) => {
|
|
6422
|
-
if (!(0,
|
|
6510
|
+
if (!(0, import_sdk21.isValidDid)(did)) {
|
|
6423
6511
|
throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
|
|
6424
6512
|
}
|
|
6425
6513
|
const api = new ArpApiClient(opts.server);
|
|
@@ -6430,33 +6518,33 @@ function registerProfileCommand(root) {
|
|
|
6430
6518
|
}
|
|
6431
6519
|
const j = false;
|
|
6432
6520
|
const s = p.reputation.scores;
|
|
6433
|
-
const live = p.liveness.online ?
|
|
6521
|
+
const live = p.liveness.online ? import_chalk23.default.green("\u25CF online") : import_chalk23.default.dim("\u25CB offline");
|
|
6434
6522
|
const tags = p.tags.map(sanitizeForTerminal).filter((t) => t.length > 0);
|
|
6435
|
-
progress(j,
|
|
6436
|
-
if (p.description) progress(j,
|
|
6437
|
-
progress(j, ` ${live}${p.liveness.inboxStreamActive ?
|
|
6438
|
-
progress(j, ` tags: ${tags.length ? tags.join(", ") :
|
|
6523
|
+
progress(j, import_chalk23.default.bold(`${p.name ? sanitizeForTerminal(p.name) : "(unnamed)"} ${import_chalk23.default.dim(p.did)}`));
|
|
6524
|
+
if (p.description) progress(j, import_chalk23.default.dim(` ${sanitizeForTerminal(p.description)}`));
|
|
6525
|
+
progress(j, ` ${live}${p.liveness.inboxStreamActive ? import_chalk23.default.green(" \xB7 stream attached") : ""} \xB7 last seen ${p.liveness.lastSeenAt ?? "\u2014"}`);
|
|
6526
|
+
progress(j, ` tags: ${tags.length ? tags.join(", ") : import_chalk23.default.dim("none")}`);
|
|
6439
6527
|
progress(j, "");
|
|
6440
|
-
progress(j,
|
|
6528
|
+
progress(j, import_chalk23.default.bold(" Reputation") + import_chalk23.default.dim(" (informational)"));
|
|
6441
6529
|
progress(
|
|
6442
6530
|
j,
|
|
6443
6531
|
` composite ${s.composite.toFixed(2)} \xB7 reliability ${s.reliability.toFixed(2)} \xB7 settlement ${s.settlement.toFixed(2)} \xB7 dispute-health ${s.disputeHealth.toFixed(2)}`
|
|
6444
6532
|
);
|
|
6445
|
-
progress(j,
|
|
6533
|
+
progress(j, import_chalk23.default.dim(` ${p.reputation.computed ? `computed ${p.reputation.lastComputedAt}` : "never computed (neutral cold-start)"}`));
|
|
6446
6534
|
});
|
|
6447
6535
|
}
|
|
6448
6536
|
|
|
6449
6537
|
// src/commands/receipt.ts
|
|
6450
|
-
var
|
|
6538
|
+
var import_sdk22 = require("@heyanon-arp/sdk");
|
|
6451
6539
|
var import_shield2 = require("@heyanon-arp/shield");
|
|
6452
|
-
var
|
|
6540
|
+
var import_chalk24 = __toESM(require("chalk"));
|
|
6453
6541
|
init_api();
|
|
6454
6542
|
function registerReceiptCommands(root) {
|
|
6455
6543
|
const cmd = root.command("receipt").description("Receipt envelopes \u2014 the payee proposes a delivery record (payment consent is on-chain via claim_work_payment)");
|
|
6456
6544
|
registerPropose(cmd);
|
|
6457
6545
|
}
|
|
6458
6546
|
function registerPropose(parent) {
|
|
6459
|
-
parent.command("propose").description("Send a receipt envelope as the PAYEE. Row lands PROPOSED; the buyer approves payment on-chain via claim_work_payment.").argument("<recipient
|
|
6547
|
+
parent.command("propose").description("Send a receipt envelope as the PAYEE. Row lands PROPOSED; the buyer approves payment on-chain via claim_work_payment.").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (= caller / offerer of the parent delegation)").argument("<delegation-id>", "Parent delegation id (UUID, must be ACCEPTED)").argument("[request-hash]", "sha256:<64 hex> \u2014 SHA-256 of the work_request payload being settled. Omit when --auto-hashes is set.").argument("[response-hash]", "sha256:<64 hex> \u2014 SHA-256 of the work_response payload being settled. Omit when --auto-hashes is set.").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("--verdict <s>", "verdict_proposed (accepted | accepted_with_notes | rejected)", "accepted").option("--notes-hash <sha256>", "Optional sha256:<64 hex> notes hash").option("--deliverable-hash <sha256>", "Optional sha256:<64 hex> deliverable hash").option("--input-tokens <n>", "Optional usage.input_tokens").option("--output-tokens <n>", "Optional usage.output_tokens").option("--latency-ms <n>", "Optional usage.latency_ms").option("--model <name>", "Optional usage.model").option("--computed-amount <s>", "Optional usage.computed_amount").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").option(
|
|
6460
6548
|
"--auto-hashes",
|
|
6461
6549
|
"Compute request_hash + response_hash automatically from the work-log row at (--rel-id, <delegation-id>, --request-id). Positional <request-hash>/<response-hash> become optional; if supplied they must match the computed values (consistency check). --rel-id and --request-id auto-resolve from local state when unambiguous \u2014 pass them explicitly only if the lookup finds multiple candidates.",
|
|
6462
6550
|
false
|
|
@@ -6476,7 +6564,7 @@ function registerPropose(parent) {
|
|
|
6476
6564
|
} catch (err) {
|
|
6477
6565
|
emitActionError(err, cmd);
|
|
6478
6566
|
if (!opts.json && err instanceof ApiError && err.payload.code === "RECEIPT_ALREADY_EXISTS") {
|
|
6479
|
-
console.error(
|
|
6567
|
+
console.error(import_chalk24.default.dim(" This receipt already exists (a prior propose committed it). Do NOT re-propose \u2014 payment consent is on-chain (claim_work_payment)."));
|
|
6480
6568
|
}
|
|
6481
6569
|
process.exitCode = 1;
|
|
6482
6570
|
}
|
|
@@ -6488,7 +6576,7 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6488
6576
|
"receipt propose: --verbose and --json are mutually exclusive. --json already emits the full server response as a structured payload; --verbose adds an envelope + response dump on top that would break `--json | jq`."
|
|
6489
6577
|
);
|
|
6490
6578
|
}
|
|
6491
|
-
|
|
6579
|
+
recipientDid = await resolveRecipient(opts.server, "receipt propose", recipientDid, { json: opts.json });
|
|
6492
6580
|
delegationId = requireUuidNormalised2("receipt propose", delegationId, "<delegation-id>");
|
|
6493
6581
|
if (opts.relId) opts.relId = requireUuidNormalised2("receipt propose", opts.relId, "--rel-id");
|
|
6494
6582
|
const verdict = parseVerdict("receipt propose", opts.verdict);
|
|
@@ -6502,7 +6590,7 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6502
6590
|
opts.relId = await resolveAutoRelId(api, sender, delegationId);
|
|
6503
6591
|
progress(
|
|
6504
6592
|
opts.json,
|
|
6505
|
-
|
|
6593
|
+
import_chalk24.default.dim(`[auto-rel-id] resolved --rel-id=${opts.relId} (delegation found in exactly one of your relationships; pass --rel-id explicitly to override)`)
|
|
6506
6594
|
);
|
|
6507
6595
|
}
|
|
6508
6596
|
if (opts.relId) {
|
|
@@ -6518,7 +6606,7 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6518
6606
|
opts.requestId = await resolveAutoRequestId(api, sender, opts.relId, delegationId);
|
|
6519
6607
|
progress(
|
|
6520
6608
|
opts.json,
|
|
6521
|
-
|
|
6609
|
+
import_chalk24.default.dim(
|
|
6522
6610
|
`[auto-request-id] resolved --request-id=${opts.requestId} (unique 'responded' work_log under this delegation; pass --request-id explicitly to override)`
|
|
6523
6611
|
)
|
|
6524
6612
|
);
|
|
@@ -6537,8 +6625,8 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6537
6625
|
}
|
|
6538
6626
|
requestHash = computed.requestHash;
|
|
6539
6627
|
responseHash = computed.responseHash;
|
|
6540
|
-
progress(opts.json,
|
|
6541
|
-
progress(opts.json,
|
|
6628
|
+
progress(opts.json, import_chalk24.default.dim(`[auto-hashes] request_hash: ${requestHash} (from work-log ${opts.relId}/${delegationId}/${opts.requestId})`));
|
|
6629
|
+
progress(opts.json, import_chalk24.default.dim(`[auto-hashes] response_hash: ${responseHash}`));
|
|
6542
6630
|
} else {
|
|
6543
6631
|
if (requestHashArg === void 0 || responseHashArg === void 0) {
|
|
6544
6632
|
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)");
|
|
@@ -6558,11 +6646,11 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6558
6646
|
if (opts.deliverableHash) content.deliverable_hash = opts.deliverableHash;
|
|
6559
6647
|
if (usage) content.usage = usage;
|
|
6560
6648
|
const body = { type: "receipt", content };
|
|
6561
|
-
progress(opts.json,
|
|
6562
|
-
progress(opts.json,
|
|
6563
|
-
progress(opts.json,
|
|
6564
|
-
progress(opts.json,
|
|
6565
|
-
progress(opts.json,
|
|
6649
|
+
progress(opts.json, import_chalk24.default.dim(`Server: ${api.serverUrl}`));
|
|
6650
|
+
progress(opts.json, import_chalk24.default.dim(`Sender (payee): ${sender.did}`));
|
|
6651
|
+
progress(opts.json, import_chalk24.default.dim(`Recipient (caller): ${recipientDid}`));
|
|
6652
|
+
progress(opts.json, import_chalk24.default.dim(`Delegation: ${delegationId}`));
|
|
6653
|
+
progress(opts.json, import_chalk24.default.dim(`Verdict (proposed): ${verdict}`));
|
|
6566
6654
|
const result = await sendReceiptEnvelope({ api, sender, recipientDid, body, attachments: void 0, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
6567
6655
|
if (opts.json) {
|
|
6568
6656
|
const json = {
|
|
@@ -6583,10 +6671,10 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
6583
6671
|
return;
|
|
6584
6672
|
}
|
|
6585
6673
|
printIngestResult2(result);
|
|
6586
|
-
console.log(
|
|
6587
|
-
Receipt event hash: ${
|
|
6588
|
-
console.log(
|
|
6589
|
-
console.log(
|
|
6674
|
+
console.log(import_chalk24.default.dim(`
|
|
6675
|
+
Receipt event hash: ${import_chalk24.default.cyan(result.serverEventHash)}`));
|
|
6676
|
+
console.log(import_chalk24.default.dim("Receipt recorded. Payment consent is ON-CHAIN now: the buyer approves by"));
|
|
6677
|
+
console.log(import_chalk24.default.dim("sending claim_work_payment (or you self-claim after the review window)."));
|
|
6590
6678
|
}
|
|
6591
6679
|
async function assertSenderIsReceiptPayee(api, sender, relationshipId, delegationId) {
|
|
6592
6680
|
const signer = makeSigner(sender);
|
|
@@ -6654,7 +6742,7 @@ async function computeWorkLogHashes(api, sender, relationshipId, delegationId, r
|
|
|
6654
6742
|
`receipt propose --auto-hashes: no work-log row found for (relationshipId=${relationshipId}, delegationId=${delegationId}, requestId=${requestId}). Did the work_request envelope land yet?`
|
|
6655
6743
|
);
|
|
6656
6744
|
}
|
|
6657
|
-
if (workLog.state !==
|
|
6745
|
+
if (workLog.state !== import_sdk22.WorkLogStates.RESPONDED) {
|
|
6658
6746
|
throw new Error(
|
|
6659
6747
|
`receipt propose --auto-hashes: work-log row ${requestId} is in state '${workLog.state}', not 'responded'. The payee must \`work respond\` before a receipt can be proposed.`
|
|
6660
6748
|
);
|
|
@@ -6670,34 +6758,34 @@ async function computeWorkLogHashes(api, sender, relationshipId, delegationId, r
|
|
|
6670
6758
|
};
|
|
6671
6759
|
const responseBody = workLog.responseOutput !== void 0 ? { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, output: workLog.responseOutput } } : { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, error: workLog.responseError } };
|
|
6672
6760
|
return {
|
|
6673
|
-
requestHash: (0,
|
|
6674
|
-
responseHash: (0,
|
|
6761
|
+
requestHash: (0, import_sdk22.canonicalSha256Hex)(requestBody),
|
|
6762
|
+
responseHash: (0, import_sdk22.canonicalSha256Hex)(responseBody)
|
|
6675
6763
|
};
|
|
6676
6764
|
}
|
|
6677
6765
|
async function sendReceiptEnvelope(args) {
|
|
6678
6766
|
const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
|
|
6679
6767
|
const protectedBlock = {
|
|
6680
|
-
protocol_version:
|
|
6681
|
-
purpose:
|
|
6682
|
-
message_id: (0,
|
|
6768
|
+
protocol_version: import_sdk22.CURRENT_PROTOCOL_VERSION,
|
|
6769
|
+
purpose: import_sdk22.Purpose.ENVELOPE,
|
|
6770
|
+
message_id: (0, import_sdk22.uuidV4)(),
|
|
6683
6771
|
sender_did: args.sender.did,
|
|
6684
6772
|
recipient_did: args.recipientDid,
|
|
6685
6773
|
relationship_id: null,
|
|
6686
6774
|
sender_sequence: nextSequence,
|
|
6687
|
-
sender_nonce: (0,
|
|
6688
|
-
timestamp: (0,
|
|
6689
|
-
expires_at: (0,
|
|
6775
|
+
sender_nonce: (0, import_sdk22.senderNonce)(),
|
|
6776
|
+
timestamp: (0, import_sdk22.rfc3339)(),
|
|
6777
|
+
expires_at: (0, import_sdk22.expiresAt)(args.ttlSeconds),
|
|
6690
6778
|
delivery_id: null
|
|
6691
6779
|
};
|
|
6692
6780
|
const signer = makeSigner(args.sender);
|
|
6693
|
-
const envelope = (0,
|
|
6781
|
+
const envelope = (0, import_sdk22.signEnvelope)({
|
|
6694
6782
|
protected: protectedBlock,
|
|
6695
6783
|
body: args.body,
|
|
6696
6784
|
identitySecretKey: signer.identitySecretKey,
|
|
6697
6785
|
attachments: args.attachments
|
|
6698
6786
|
});
|
|
6699
6787
|
if (args.verbose) {
|
|
6700
|
-
console.log(
|
|
6788
|
+
console.log(import_chalk24.default.bold("\nEnvelope (pre-send):"));
|
|
6701
6789
|
console.log(formatJson(envelope));
|
|
6702
6790
|
}
|
|
6703
6791
|
try {
|
|
@@ -6705,24 +6793,24 @@ async function sendReceiptEnvelope(args) {
|
|
|
6705
6793
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
6706
6794
|
return result;
|
|
6707
6795
|
} catch (err) {
|
|
6708
|
-
if (err instanceof ApiError && (0,
|
|
6796
|
+
if (err instanceof ApiError && (0, import_sdk22.isPostCommitErrorCode)(err.payload.code)) {
|
|
6709
6797
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
6710
6798
|
}
|
|
6711
6799
|
throw err;
|
|
6712
6800
|
}
|
|
6713
6801
|
}
|
|
6714
6802
|
function printIngestResult2(result) {
|
|
6715
|
-
console.log(
|
|
6716
|
-
console.log(`${
|
|
6717
|
-
console.log(`${
|
|
6718
|
-
console.log(`${
|
|
6719
|
-
console.log(`${
|
|
6720
|
-
console.log(`${
|
|
6803
|
+
console.log(import_chalk24.default.green("\nDelivered."));
|
|
6804
|
+
console.log(`${import_chalk24.default.bold("Event id")}: ${import_chalk24.default.cyan(result.eventId)}`);
|
|
6805
|
+
console.log(`${import_chalk24.default.bold("Relationship id")}: ${import_chalk24.default.cyan(result.relationshipId)}`);
|
|
6806
|
+
console.log(`${import_chalk24.default.bold("Chain index")}: ${import_chalk24.default.cyan(String(result.relationshipEventIndex))}`);
|
|
6807
|
+
console.log(`${import_chalk24.default.bold("Server timestamp")}: ${import_chalk24.default.cyan(result.serverTimestamp)}`);
|
|
6808
|
+
console.log(`${import_chalk24.default.bold("Server event hash")}: ${import_chalk24.default.cyan(result.serverEventHash)}`);
|
|
6721
6809
|
}
|
|
6722
6810
|
function parseVerdict(cmdName, raw) {
|
|
6723
|
-
if (raw === void 0 || raw === "") return
|
|
6724
|
-
if (!
|
|
6725
|
-
throw new Error(`${cmdName}: --verdict must be one of ${
|
|
6811
|
+
if (raw === void 0 || raw === "") return import_sdk22.ReceiptVerdicts.ACCEPTED;
|
|
6812
|
+
if (!import_sdk22.RECEIPT_VERDICTS.includes(raw)) {
|
|
6813
|
+
throw new Error(`${cmdName}: --verdict must be one of ${import_sdk22.RECEIPT_VERDICTS.join(" | ")} (got '${raw}')`);
|
|
6726
6814
|
}
|
|
6727
6815
|
return raw;
|
|
6728
6816
|
}
|
|
@@ -6759,19 +6847,14 @@ function requireUuid3(cmdName, raw, label) {
|
|
|
6759
6847
|
requireUuid(cmdName, raw, label);
|
|
6760
6848
|
}
|
|
6761
6849
|
function requireSha256(cmdName, raw, label) {
|
|
6762
|
-
if (!(0,
|
|
6850
|
+
if (!(0, import_sdk22.isSha256Hex)(raw)) {
|
|
6763
6851
|
throw new Error(`${cmdName}: ${label} must match 'sha256:<64 lowercase hex>' (got '${raw}')`);
|
|
6764
6852
|
}
|
|
6765
6853
|
}
|
|
6766
|
-
function requireDid2(cmdName, did, label) {
|
|
6767
|
-
if (typeof did !== "string" || !did.startsWith("did:arp:") || did.length <= "did:arp:".length) {
|
|
6768
|
-
throw new Error(`${cmdName}: ${label} must look like 'did:arp:...' (got '${did}')`);
|
|
6769
|
-
}
|
|
6770
|
-
}
|
|
6771
6854
|
|
|
6772
6855
|
// src/commands/receipts.ts
|
|
6773
|
-
var
|
|
6774
|
-
var
|
|
6856
|
+
var import_sdk23 = require("@heyanon-arp/sdk");
|
|
6857
|
+
var import_chalk25 = __toESM(require("chalk"));
|
|
6775
6858
|
init_api();
|
|
6776
6859
|
function registerReceiptsCommand(root) {
|
|
6777
6860
|
root.command("receipts").description(
|
|
@@ -6794,9 +6877,9 @@ async function runReceipts(relationshipId, opts) {
|
|
|
6794
6877
|
const api = new ArpApiClient(opts.server);
|
|
6795
6878
|
const sender = resolveSenderAgent("receipts", opts.server, opts.fromDid);
|
|
6796
6879
|
if (!opts.json) {
|
|
6797
|
-
console.log(
|
|
6798
|
-
console.log(
|
|
6799
|
-
console.log(
|
|
6880
|
+
console.log(import_chalk25.default.dim(`Server: ${api.serverUrl}`));
|
|
6881
|
+
console.log(import_chalk25.default.dim(`Signer: ${sender.did}`));
|
|
6882
|
+
console.log(import_chalk25.default.dim(`Relationship: ${relationshipId}`));
|
|
6800
6883
|
}
|
|
6801
6884
|
const query = { limit };
|
|
6802
6885
|
if (opts.delegationId) query.delegationId = opts.delegationId;
|
|
@@ -6808,7 +6891,7 @@ async function runReceipts(relationshipId, opts) {
|
|
|
6808
6891
|
return;
|
|
6809
6892
|
}
|
|
6810
6893
|
if (rows.length === 0) {
|
|
6811
|
-
console.log(
|
|
6894
|
+
console.log(import_chalk25.default.dim("\n(no receipts for this relationship)"));
|
|
6812
6895
|
return;
|
|
6813
6896
|
}
|
|
6814
6897
|
console.log("");
|
|
@@ -6825,29 +6908,29 @@ async function runReceipts(relationshipId, opts) {
|
|
|
6825
6908
|
}));
|
|
6826
6909
|
}
|
|
6827
6910
|
const lastId = rows[rows.length - 1].id;
|
|
6828
|
-
console.log(
|
|
6911
|
+
console.log(import_chalk25.default.dim(`
|
|
6829
6912
|
${rows.length} receipt row(s). Paginate with --after ${lastId}.`));
|
|
6830
6913
|
}
|
|
6831
6914
|
function formatReceiptLine(r, selfDid, opts = {}) {
|
|
6832
6915
|
const delegationPart = opts.fullIds ? r.delegationId : idHead2(r.delegationId);
|
|
6833
6916
|
const requestHashPart = opts.fullIds ? r.requestHash : hashHead3(r.requestHash);
|
|
6834
|
-
const id =
|
|
6917
|
+
const id = import_chalk25.default.bold(`${delegationPart}/${requestHashPart}`);
|
|
6835
6918
|
const callerHead = opts.fullIds ? r.callerDid : didHead3(r.callerDid);
|
|
6836
6919
|
const payeeHead = opts.fullIds ? r.payeeDid : didHead3(r.payeeDid);
|
|
6837
|
-
const direction = r.payeeDid === selfDid ? `${
|
|
6920
|
+
const direction = r.payeeDid === selfDid ? `${import_chalk25.default.bold("me")}(payee) \u2192 ${import_chalk25.default.dim(callerHead)}` : `${import_chalk25.default.dim(payeeHead)}(payee) \u2192 ${import_chalk25.default.bold("me")}`;
|
|
6838
6921
|
const verdict = formatVerdict(r);
|
|
6839
6922
|
const responseTail = opts.fullIds ? `
|
|
6840
|
-
${
|
|
6923
|
+
${import_chalk25.default.dim("responseHash:")} ${import_chalk25.default.cyan(r.responseHash)}` : "";
|
|
6841
6924
|
return `${id} ${direction} ${verdict}${responseTail}`;
|
|
6842
6925
|
}
|
|
6843
6926
|
function formatVerdict(r) {
|
|
6844
6927
|
switch (r.verdictProposed) {
|
|
6845
|
-
case
|
|
6846
|
-
return
|
|
6847
|
-
case
|
|
6848
|
-
return
|
|
6849
|
-
case
|
|
6850
|
-
return
|
|
6928
|
+
case import_sdk23.ReceiptVerdicts.ACCEPTED:
|
|
6929
|
+
return import_chalk25.default.green("accepted");
|
|
6930
|
+
case import_sdk23.ReceiptVerdicts.ACCEPTED_WITH_NOTES:
|
|
6931
|
+
return import_chalk25.default.yellow("accepted_with_notes");
|
|
6932
|
+
case import_sdk23.ReceiptVerdicts.REJECTED:
|
|
6933
|
+
return import_chalk25.default.red("rejected");
|
|
6851
6934
|
}
|
|
6852
6935
|
}
|
|
6853
6936
|
function idHead2(id) {
|
|
@@ -6873,8 +6956,8 @@ function parseLimit5(raw) {
|
|
|
6873
6956
|
|
|
6874
6957
|
// src/commands/recover.ts
|
|
6875
6958
|
var import_node_fs8 = require("fs");
|
|
6876
|
-
var
|
|
6877
|
-
var
|
|
6959
|
+
var import_sdk24 = require("@heyanon-arp/sdk");
|
|
6960
|
+
var import_chalk26 = __toESM(require("chalk"));
|
|
6878
6961
|
init_api();
|
|
6879
6962
|
function registerRecoverCommand(root) {
|
|
6880
6963
|
root.command("recover").description(
|
|
@@ -6894,23 +6977,23 @@ async function runRecover(opts) {
|
|
|
6894
6977
|
}
|
|
6895
6978
|
const bundle = validateKeyBundle(raw);
|
|
6896
6979
|
const identitySecret = new Uint8Array(Buffer.from(bundle.identitySecretKeyB64, "base64"));
|
|
6897
|
-
const identityPub = (0,
|
|
6898
|
-
const derivedDid = (0,
|
|
6980
|
+
const identityPub = (0, import_sdk24.base58btcDecode)(bundle.identityPublicKeyB58);
|
|
6981
|
+
const derivedDid = (0, import_sdk24.formatDid)(identityPub);
|
|
6899
6982
|
if (derivedDid !== bundle.did) {
|
|
6900
6983
|
throw new Error(`recover: key file is inconsistent \u2014 its DID (${bundle.did}) does not match its identity public key (${derivedDid})`);
|
|
6901
6984
|
}
|
|
6902
6985
|
const probe2 = new TextEncoder().encode("heyarp-recover-keycheck");
|
|
6903
|
-
if (!(0,
|
|
6986
|
+
if (!(0, import_sdk24.verify)((0, import_sdk24.sign)(probe2, identitySecret), probe2, identityPub)) {
|
|
6904
6987
|
throw new Error("recover: the identity secret key does not match the public key in this bundle");
|
|
6905
6988
|
}
|
|
6906
6989
|
const settlementSecret = new Uint8Array(Buffer.from(bundle.settlementSecretKeyB64, "base64"));
|
|
6907
|
-
const settlementPub = (0,
|
|
6908
|
-
if (!(0,
|
|
6990
|
+
const settlementPub = (0, import_sdk24.base58btcDecode)(bundle.settlementPublicKeyB58);
|
|
6991
|
+
if (!(0, import_sdk24.verify)((0, import_sdk24.sign)(probe2, settlementSecret), probe2, settlementPub)) {
|
|
6909
6992
|
throw new Error("recover: the settlement secret key does not match the settlement public key in this bundle");
|
|
6910
6993
|
}
|
|
6911
6994
|
if (bundle.ownerWallet && bundle.ownerWallet !== credential.wallet) {
|
|
6912
6995
|
process.stderr.write(
|
|
6913
|
-
|
|
6996
|
+
import_chalk26.default.yellow(
|
|
6914
6997
|
`\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.
|
|
6915
6998
|
`
|
|
6916
6999
|
)
|
|
@@ -6927,7 +7010,7 @@ async function runRecover(opts) {
|
|
|
6927
7010
|
lastSenderSequence = seq.lastSenderSequence;
|
|
6928
7011
|
} catch (err) {
|
|
6929
7012
|
process.stderr.write(
|
|
6930
|
-
|
|
7013
|
+
import_chalk26.default.yellow(
|
|
6931
7014
|
`\u26A0 could not read the sender sequence from the server (${err.message}). If sends are rejected as backwards, run \`heyarp escrow recover-sequence --apply\`.
|
|
6932
7015
|
`
|
|
6933
7016
|
)
|
|
@@ -6955,14 +7038,14 @@ async function runRecover(opts) {
|
|
|
6955
7038
|
jsonOut({ recovered: true, did: derivedDid, name: row.name });
|
|
6956
7039
|
return;
|
|
6957
7040
|
}
|
|
6958
|
-
console.log(
|
|
7041
|
+
console.log(import_chalk26.default.green(`\u2713 Recovered ${row.name ? `${row.name} ` : ""}${derivedDid} into local state \u2014 you can operate it now.`));
|
|
6959
7042
|
}
|
|
6960
7043
|
|
|
6961
7044
|
// src/commands/register.ts
|
|
6962
7045
|
var import_node_crypto4 = require("crypto");
|
|
6963
7046
|
var import_node_fs9 = require("fs");
|
|
6964
|
-
var
|
|
6965
|
-
var
|
|
7047
|
+
var import_sdk25 = require("@heyanon-arp/sdk");
|
|
7048
|
+
var import_chalk27 = __toESM(require("chalk"));
|
|
6966
7049
|
var import_prompts2 = __toESM(require("prompts"));
|
|
6967
7050
|
init_api();
|
|
6968
7051
|
init_paths();
|
|
@@ -6974,7 +7057,7 @@ function registerRegisterCommand(root) {
|
|
|
6974
7057
|
"`--password` is REQUIRED \u2014 must be at least 8 characters. In interactive mode (--yes omitted) the CLI prompts for it; with --yes it must be passed explicitly.",
|
|
6975
7058
|
"`--yes` is the non-interactive switch \u2014 every required field must arrive via flags (no prompts). Use this for scripted setups."
|
|
6976
7059
|
].join("\n")
|
|
6977
|
-
).option("--server <url>", "Override ARP server base URL").option("--from-keys <file>", "Load identity + settlement keys from a JSON file instead of generating").option("--name <s>", "
|
|
7060
|
+
).option("--server <url>", "Override ARP server base URL").option("--from-keys <file>", "Load identity + settlement keys from a JSON file instead of generating").option("--name <s>", "Unique handle \u2014 lowercase a-z0-9_, 3-32 chars, immutable (skips the name prompt)").option("--description <s>", "Description (skips the description prompt)").option("--tag <s>", "Capability tag \u2014 repeatable, e.g. --tag translation --tag fr", accumulate3, []).option(
|
|
6978
7061
|
"--password <s>",
|
|
6979
7062
|
// `--password` puts the secret in `argv` — visible via
|
|
6980
7063
|
// `ps aux` / kernel process table on shared hosts,
|
|
@@ -7016,44 +7099,44 @@ var defaultRegisterDeps = {
|
|
|
7016
7099
|
async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
7017
7100
|
assertJsonRequiresYes(opts);
|
|
7018
7101
|
const api = deps.makeApi(opts.server);
|
|
7019
|
-
if (!opts.json) console.log(
|
|
7102
|
+
if (!opts.json) console.log(import_chalk27.default.dim(`Server: ${api.serverUrl}`));
|
|
7020
7103
|
const credential = requireCredential("register", api.serverUrl);
|
|
7021
7104
|
if (!opts.json) {
|
|
7022
7105
|
warnIfAgentsAlreadyRegistered(opts.server);
|
|
7023
7106
|
warnIfOrphanHomesPresent();
|
|
7024
7107
|
}
|
|
7025
7108
|
const keys = opts.fromKeys ? loadKeysFromFile(opts.fromKeys) : freshKeys();
|
|
7026
|
-
const did = (0,
|
|
7027
|
-
if (!opts.json) console.log(
|
|
7109
|
+
const did = (0, import_sdk25.formatDid)(keys.identityPublicKey);
|
|
7110
|
+
if (!opts.json) console.log(import_chalk27.default.dim(`DID will be: ${did}`));
|
|
7028
7111
|
const answers = await mergeAnswers(opts);
|
|
7029
7112
|
const scryptSalt = (0, import_node_crypto4.randomBytes)(16);
|
|
7030
|
-
if (!opts.json) console.log(
|
|
7031
|
-
const scryptKey = (0,
|
|
7113
|
+
if (!opts.json) console.log(import_chalk27.default.dim("Deriving scrypt key, this may take a moment..."));
|
|
7114
|
+
const scryptKey = (0, import_sdk25.deriveScryptKey)(answers.password, new Uint8Array(scryptSalt));
|
|
7032
7115
|
const challenge = await api.issueChallenge("register");
|
|
7033
7116
|
const challengeBytes = base64UrlNoPadDecode(challenge.challengeB64);
|
|
7034
7117
|
if (challengeBytes.length !== 32) {
|
|
7035
7118
|
throw new Error(`Server returned a ${challengeBytes.length}-byte challenge; expected 32`);
|
|
7036
7119
|
}
|
|
7037
|
-
const challengeSig = (0,
|
|
7038
|
-
const identityPublicKeyB58 = (0,
|
|
7120
|
+
const challengeSig = (0, import_sdk25.signChallenge)(challengeBytes, keys.identitySecretKey);
|
|
7121
|
+
const identityPublicKeyB58 = (0, import_sdk25.base58btcEncode)(keys.identityPublicKey);
|
|
7039
7122
|
await api.submitChallengeResponse({
|
|
7040
7123
|
challengeId: challenge.challengeId,
|
|
7041
7124
|
identityPublicKey: identityPublicKeyB58,
|
|
7042
7125
|
signature: Buffer.from(challengeSig).toString("base64")
|
|
7043
7126
|
});
|
|
7044
|
-
const settlementPublicKeyB58 = (0,
|
|
7045
|
-
const scryptSaltId = (0,
|
|
7127
|
+
const settlementPublicKeyB58 = (0, import_sdk25.base58btcEncode)(keys.settlementPublicKey);
|
|
7128
|
+
const scryptSaltId = (0, import_sdk25.uuidV4)();
|
|
7046
7129
|
const payload = {
|
|
7047
|
-
purpose:
|
|
7130
|
+
purpose: import_sdk25.Purpose.KEY_LINK,
|
|
7048
7131
|
agent_did: did,
|
|
7049
7132
|
identity_public_key: identityPublicKeyB58,
|
|
7050
7133
|
settlement_public_key: settlementPublicKeyB58,
|
|
7051
|
-
owner_signing_method:
|
|
7134
|
+
owner_signing_method: import_sdk25.OWNER_SIGNING_METHODS[0],
|
|
7052
7135
|
link_method: "manual",
|
|
7053
|
-
created_at: (0,
|
|
7054
|
-
nonce: (0,
|
|
7136
|
+
created_at: (0, import_sdk25.rfc3339)(),
|
|
7137
|
+
nonce: (0, import_sdk25.senderNonce)()
|
|
7055
7138
|
};
|
|
7056
|
-
const attestation = (0,
|
|
7139
|
+
const attestation = (0, import_sdk25.signKeyLinkAttestation)({ payload, scryptKey, scryptSaltId });
|
|
7057
7140
|
const body = {
|
|
7058
7141
|
challengeId: challenge.challengeId,
|
|
7059
7142
|
identityPublicKey: identityPublicKeyB58,
|
|
@@ -7096,7 +7179,7 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
7096
7179
|
try {
|
|
7097
7180
|
result = await api.register(body, credential.token);
|
|
7098
7181
|
} catch (err) {
|
|
7099
|
-
if (err instanceof ApiError && (err.payload.code ===
|
|
7182
|
+
if (err instanceof ApiError && (err.payload.code === import_sdk25.CliAuthTokenErrorCodes.INVALID || err.payload.code === import_sdk25.CliAuthTokenErrorCodes.REQUIRED)) {
|
|
7100
7183
|
throw new Error(
|
|
7101
7184
|
`register: the stored login token for ${api.serverUrl} was rejected (${err.payload.message}) \u2014 run 'heyarp login' again. Your keys are saved locally; re-running register with --from-keys is safe.`
|
|
7102
7185
|
);
|
|
@@ -7115,19 +7198,19 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
7115
7198
|
try {
|
|
7116
7199
|
recordHome(arpHomeDir());
|
|
7117
7200
|
} catch (registryErr) {
|
|
7118
|
-
if (!opts.json) console.log(
|
|
7201
|
+
if (!opts.json) console.log(import_chalk27.default.dim(`(homes registry write failed: ${registryErr.message})`));
|
|
7119
7202
|
}
|
|
7120
7203
|
if (!opts.json) {
|
|
7121
|
-
console.log(
|
|
7122
|
-
console.log(`${
|
|
7123
|
-
console.log(`${
|
|
7124
|
-
console.log(`${
|
|
7125
|
-
console.log(
|
|
7204
|
+
console.log(import_chalk27.default.green("\nRegistered."));
|
|
7205
|
+
console.log(`${import_chalk27.default.bold("DID")}: ${import_chalk27.default.cyan(result.did)}`);
|
|
7206
|
+
console.log(`${import_chalk27.default.bold("Settlement pubkey")} ${import_chalk27.default.dim("(fund with SOL)")}: ${import_chalk27.default.cyan(settlementPublicKeyB58)}`);
|
|
7207
|
+
console.log(`${import_chalk27.default.bold("Owner account")}: ${import_chalk27.default.cyan(credential.wallet)}`);
|
|
7208
|
+
console.log(import_chalk27.default.bold("DID document:"));
|
|
7126
7209
|
console.log(formatJson(result.didDocument));
|
|
7127
7210
|
}
|
|
7128
|
-
if (!opts.json) console.log(
|
|
7211
|
+
if (!opts.json) console.log(import_chalk27.default.green(`
|
|
7129
7212
|
\u2713 Discoverable now via \`heyarp agents\`.`));
|
|
7130
|
-
if (!opts.json) console.log(
|
|
7213
|
+
if (!opts.json) console.log(import_chalk27.default.dim(`
|
|
7131
7214
|
Local state saved to ${arpHomeDir()}/agents.json (mode 0600).`));
|
|
7132
7215
|
if (opts.json) {
|
|
7133
7216
|
console.log(
|
|
@@ -7178,8 +7261,13 @@ async function mergeAnswers(opts) {
|
|
|
7178
7261
|
promptDefs.push({
|
|
7179
7262
|
type: "text",
|
|
7180
7263
|
name: "name",
|
|
7181
|
-
message: "Agent name (
|
|
7182
|
-
validate: (v) =>
|
|
7264
|
+
message: "Agent name \u2014 unique handle (lowercase a-z0-9_, 3-32 chars, immutable; addressable instead of the DID)",
|
|
7265
|
+
validate: (v) => {
|
|
7266
|
+
const n = (0, import_sdk25.normalizeName)(v);
|
|
7267
|
+
if (!(0, import_sdk25.isValidAgentName)(n)) return "must be lowercase a-z0-9_, 3-32 chars";
|
|
7268
|
+
if ((0, import_sdk25.isReservedName)(n)) return `'${n}' is reserved`;
|
|
7269
|
+
return true;
|
|
7270
|
+
}
|
|
7183
7271
|
});
|
|
7184
7272
|
}
|
|
7185
7273
|
if (need.description) {
|
|
@@ -7195,18 +7283,29 @@ async function mergeAnswers(opts) {
|
|
|
7195
7283
|
}
|
|
7196
7284
|
const prompted = promptDefs.length > 0 ? await (0, import_prompts2.default)(promptDefs, {
|
|
7197
7285
|
onCancel: () => {
|
|
7198
|
-
console.log(
|
|
7286
|
+
console.log(import_chalk27.default.yellow("\nAborted."));
|
|
7199
7287
|
process.exit(130);
|
|
7200
7288
|
}
|
|
7201
7289
|
}) : {};
|
|
7202
7290
|
const tags = (opts.tag && opts.tag.length > 0 ? opts.tag : parseTagsCsv(typeof prompted.tagsCsv === "string" ? prompted.tagsCsv : "")).map((t) => t.trim().toLowerCase()).filter((t) => t.length > 0);
|
|
7291
|
+
const name = normalizeAndValidateName(opts.name ?? prompted.name);
|
|
7203
7292
|
return {
|
|
7204
7293
|
password: opts.password ?? prompted.password,
|
|
7205
|
-
name
|
|
7294
|
+
name,
|
|
7206
7295
|
description: opts.description ?? prompted.description ?? "",
|
|
7207
7296
|
tags
|
|
7208
7297
|
};
|
|
7209
7298
|
}
|
|
7299
|
+
function normalizeAndValidateName(raw) {
|
|
7300
|
+
const name = (0, import_sdk25.normalizeName)(raw);
|
|
7301
|
+
if (!(0, import_sdk25.isValidAgentName)(name)) {
|
|
7302
|
+
throw new Error(`register: name '${raw}' must be a lowercase handle \u2014 a-z0-9_, 3-32 chars`);
|
|
7303
|
+
}
|
|
7304
|
+
if ((0, import_sdk25.isReservedName)(name)) {
|
|
7305
|
+
throw new Error(`register: name '${name}' is reserved and cannot be registered`);
|
|
7306
|
+
}
|
|
7307
|
+
return name;
|
|
7308
|
+
}
|
|
7210
7309
|
function warnIfOrphanHomesPresent() {
|
|
7211
7310
|
if (process.env.HEYARP_HOME && process.env.HEYARP_HOME.length > 0) {
|
|
7212
7311
|
return;
|
|
@@ -7216,16 +7315,16 @@ function warnIfOrphanHomesPresent() {
|
|
|
7216
7315
|
try {
|
|
7217
7316
|
others = listHomes().filter((h) => h.path !== current);
|
|
7218
7317
|
} catch (registryErr) {
|
|
7219
|
-
console.log(
|
|
7318
|
+
console.log(import_chalk27.default.dim(`(homes registry unreadable, skipping orphan-home check: ${registryErr.message})`));
|
|
7220
7319
|
return;
|
|
7221
7320
|
}
|
|
7222
7321
|
if (others.length === 0) return;
|
|
7223
|
-
const list = others.map((h) => ` \u2022 ${
|
|
7224
|
-
console.log(
|
|
7322
|
+
const list = others.map((h) => ` \u2022 ${import_chalk27.default.cyan(h.path)} ${import_chalk27.default.dim(`(last seen ${h.lastSeenAt})`)}`).join("\n");
|
|
7323
|
+
console.log(import_chalk27.default.yellow(`
|
|
7225
7324
|
\u26A0 HEYARP_HOME is unset, but other agent homes are registered on this machine:`));
|
|
7226
7325
|
console.log(list);
|
|
7227
7326
|
console.log(
|
|
7228
|
-
|
|
7327
|
+
import_chalk27.default.dim(
|
|
7229
7328
|
` Registering will create a NEW agent under ${current}.
|
|
7230
7329
|
If you meant to add to an existing home, abort (Ctrl-C) and re-run with:
|
|
7231
7330
|
HEYARP_HOME=<path> heyarp register \u2026
|
|
@@ -7238,11 +7337,11 @@ function warnIfAgentsAlreadyRegistered(serverOverride) {
|
|
|
7238
7337
|
const targetServer = resolveServerUrl(serverOverride);
|
|
7239
7338
|
const existing = listAgents().filter((row) => row.serverUrl === targetServer);
|
|
7240
7339
|
if (existing.length === 0) return;
|
|
7241
|
-
const list = existing.map((row) => ` \u2022 ${
|
|
7242
|
-
console.log(
|
|
7340
|
+
const list = existing.map((row) => ` \u2022 ${import_chalk27.default.cyan(row.agent.did)}${row.agent.name ? import_chalk27.default.dim(` (${row.agent.name})`) : ""}`).join("\n");
|
|
7341
|
+
console.log(import_chalk27.default.yellow("\n\u26A0 ~/.heyarp/agents.json already has agent(s) for this server:"));
|
|
7243
7342
|
console.log(list);
|
|
7244
7343
|
console.log(
|
|
7245
|
-
|
|
7344
|
+
import_chalk27.default.dim(
|
|
7246
7345
|
" 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"
|
|
7247
7346
|
)
|
|
7248
7347
|
);
|
|
@@ -7252,8 +7351,8 @@ function parseTagsCsv(raw) {
|
|
|
7252
7351
|
return raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
7253
7352
|
}
|
|
7254
7353
|
function freshKeys() {
|
|
7255
|
-
const identity = (0,
|
|
7256
|
-
const settlement = (0,
|
|
7354
|
+
const identity = (0, import_sdk25.generateKeyPair)();
|
|
7355
|
+
const settlement = (0, import_sdk25.generateKeyPair)();
|
|
7257
7356
|
return {
|
|
7258
7357
|
identityPublicKey: identity.publicKey,
|
|
7259
7358
|
identitySecretKey: identity.secretKey,
|
|
@@ -7279,9 +7378,9 @@ function loadKeysFromFile(path) {
|
|
|
7279
7378
|
if (identitySecret.length !== 32) throw new Error("--from-keys: identitySecretKeyB64 is not a 32-byte Ed25519 seed");
|
|
7280
7379
|
if (settlementSecret.length !== 32) throw new Error("--from-keys: settlementSecretKeyB64 is not a 32-byte Ed25519 seed");
|
|
7281
7380
|
return {
|
|
7282
|
-
identityPublicKey: (0,
|
|
7381
|
+
identityPublicKey: (0, import_sdk25.getPublicKey)(identitySecret),
|
|
7283
7382
|
identitySecretKey: identitySecret,
|
|
7284
|
-
settlementPublicKey: (0,
|
|
7383
|
+
settlementPublicKey: (0, import_sdk25.getPublicKey)(settlementSecret),
|
|
7285
7384
|
settlementSecretKey: settlementSecret
|
|
7286
7385
|
};
|
|
7287
7386
|
}
|
|
@@ -7297,10 +7396,10 @@ function assertJsonRequiresYes(opts) {
|
|
|
7297
7396
|
}
|
|
7298
7397
|
|
|
7299
7398
|
// src/commands/relationships.ts
|
|
7300
|
-
var
|
|
7301
|
-
var
|
|
7399
|
+
var import_sdk26 = require("@heyanon-arp/sdk");
|
|
7400
|
+
var import_chalk28 = __toESM(require("chalk"));
|
|
7302
7401
|
init_api();
|
|
7303
|
-
var ALLOWED_STATES2 = new Set(
|
|
7402
|
+
var ALLOWED_STATES2 = new Set(import_sdk26.RELATIONSHIP_STATE_NAMES);
|
|
7304
7403
|
function registerRelationshipsCommand(root) {
|
|
7305
7404
|
root.command("relationships").description(
|
|
7306
7405
|
"List relationships <did> belongs to (live + closed pairs, ordered by lastEventAt desc). DID can be passed positionally OR via --from-did; if both are omitted the resolver picks the sole local agent for the server (see `heyarp config set server` + multi-DID disambiguation rules)."
|
|
@@ -7327,8 +7426,8 @@ async function runRelationships(positionalDid, opts) {
|
|
|
7327
7426
|
const local = explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("relationships", opts.server, void 0);
|
|
7328
7427
|
const did = local.did;
|
|
7329
7428
|
const api = new ArpApiClient(opts.server);
|
|
7330
|
-
progress(opts.json,
|
|
7331
|
-
progress(opts.json,
|
|
7429
|
+
progress(opts.json, import_chalk28.default.dim(`Server: ${api.serverUrl}`));
|
|
7430
|
+
progress(opts.json, import_chalk28.default.dim(`Signer: ${local.did}`));
|
|
7332
7431
|
const query = { limit };
|
|
7333
7432
|
if (state) query.state = state;
|
|
7334
7433
|
const signer = makeSigner(local);
|
|
@@ -7338,18 +7437,18 @@ async function runRelationships(positionalDid, opts) {
|
|
|
7338
7437
|
return;
|
|
7339
7438
|
}
|
|
7340
7439
|
if (rows.length === 0) {
|
|
7341
|
-
console.log(
|
|
7440
|
+
console.log(import_chalk28.default.dim("\n(no relationships)"));
|
|
7342
7441
|
return;
|
|
7343
7442
|
}
|
|
7344
7443
|
console.log("");
|
|
7345
7444
|
console.log(formatRelationshipsTable(rows, did));
|
|
7346
7445
|
if (opts.verbose) {
|
|
7347
|
-
console.log(
|
|
7446
|
+
console.log(import_chalk28.default.bold("\nFull relationships:"));
|
|
7348
7447
|
for (const r of rows) {
|
|
7349
7448
|
console.log(formatJson(r));
|
|
7350
7449
|
}
|
|
7351
7450
|
}
|
|
7352
|
-
console.log(
|
|
7451
|
+
console.log(import_chalk28.default.dim(`
|
|
7353
7452
|
${rows.length} relationship(s).`));
|
|
7354
7453
|
}
|
|
7355
7454
|
function formatRelationshipsTable(rows, selfDid) {
|
|
@@ -7357,7 +7456,7 @@ function formatRelationshipsTable(rows, selfDid) {
|
|
|
7357
7456
|
const data = rows.map((r) => [r.relationshipId, otherPair(r, selfDid), r.state, r.lastEventAt ?? "(none)", String(r.lastEventIndex)]);
|
|
7358
7457
|
const widths = header.map((h, i) => Math.max(h.length, ...data.map((row) => row[i].length)));
|
|
7359
7458
|
const pad = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
7360
|
-
return [
|
|
7459
|
+
return [import_chalk28.default.bold(pad(header)), import_chalk28.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))].join("\n");
|
|
7361
7460
|
}
|
|
7362
7461
|
function otherPair(r, selfDid) {
|
|
7363
7462
|
if (r.pairDidA === selfDid) return r.pairDidB;
|
|
@@ -7381,12 +7480,12 @@ function parseLimit6(raw) {
|
|
|
7381
7480
|
}
|
|
7382
7481
|
|
|
7383
7482
|
// src/commands/reputation.ts
|
|
7384
|
-
var
|
|
7385
|
-
var
|
|
7483
|
+
var import_sdk27 = require("@heyanon-arp/sdk");
|
|
7484
|
+
var import_chalk29 = __toESM(require("chalk"));
|
|
7386
7485
|
init_api();
|
|
7387
7486
|
function registerReputationCommand(root) {
|
|
7388
7487
|
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) => {
|
|
7389
|
-
if (!(0,
|
|
7488
|
+
if (!(0, import_sdk27.isValidDid)(did)) {
|
|
7390
7489
|
throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
|
|
7391
7490
|
}
|
|
7392
7491
|
const api = new ArpApiClient(opts.server);
|
|
@@ -7398,10 +7497,10 @@ function registerReputationCommand(root) {
|
|
|
7398
7497
|
const s = rep.scores;
|
|
7399
7498
|
const c = rep.counters;
|
|
7400
7499
|
const j = false;
|
|
7401
|
-
progress(j,
|
|
7500
|
+
progress(j, import_chalk29.default.bold(`Reputation \u2014 ${did}`));
|
|
7402
7501
|
progress(
|
|
7403
7502
|
j,
|
|
7404
|
-
|
|
7503
|
+
import_chalk29.default.dim(` ${rep.informational ? "INFORMATIONAL" : "GATING"} \xB7 ${rep.computed ? `computed ${rep.lastComputedAt}` : "never computed (neutral cold-start)"}`)
|
|
7405
7504
|
);
|
|
7406
7505
|
progress(j, "");
|
|
7407
7506
|
progress(j, ` composite ${bar(s.composite)} ${s.composite.toFixed(2)}`);
|
|
@@ -7409,17 +7508,17 @@ function registerReputationCommand(root) {
|
|
|
7409
7508
|
progress(j, ` settlement ${bar(s.settlement)} ${s.settlement.toFixed(2)}`);
|
|
7410
7509
|
progress(j, ` dispute health ${bar(s.disputeHealth)} ${s.disputeHealth.toFixed(2)}`);
|
|
7411
7510
|
progress(j, "");
|
|
7412
|
-
progress(j,
|
|
7511
|
+
progress(j, import_chalk29.default.dim(" evidence:"));
|
|
7413
7512
|
progress(
|
|
7414
7513
|
j,
|
|
7415
|
-
|
|
7514
|
+
import_chalk29.default.dim(
|
|
7416
7515
|
` on-chain cycles ${c.onchainCycles} \xB7 completed ${c.completedDelegations} (payer ${c.completedAsPayer} / payee ${c.completedAsPayee}) \xB7 failed ${c.failedDelegations}`
|
|
7417
7516
|
)
|
|
7418
7517
|
);
|
|
7419
|
-
progress(j,
|
|
7420
|
-
progress(j,
|
|
7518
|
+
progress(j, import_chalk29.default.dim(` escrows settled ${c.settledEscrows} / refunded ${c.refundedEscrows} \xB7 disputed ${c.disputedEscrows} (adverse ${c.disputesAdverse})`));
|
|
7519
|
+
progress(j, import_chalk29.default.dim(` distinct counterparts ${c.distinctCounterparts} \xB7 active relationships ${c.activeRelationships}`));
|
|
7421
7520
|
progress(j, "");
|
|
7422
|
-
progress(j,
|
|
7521
|
+
progress(j, import_chalk29.default.dim(" Informational only \u2014 a discovery-sort signal, not a money or eligibility gate."));
|
|
7423
7522
|
});
|
|
7424
7523
|
}
|
|
7425
7524
|
function bar(score) {
|
|
@@ -7428,11 +7527,11 @@ function bar(score) {
|
|
|
7428
7527
|
}
|
|
7429
7528
|
|
|
7430
7529
|
// src/commands/send-handshake.ts
|
|
7431
|
-
var
|
|
7432
|
-
var
|
|
7530
|
+
var import_sdk28 = require("@heyanon-arp/sdk");
|
|
7531
|
+
var import_chalk30 = __toESM(require("chalk"));
|
|
7433
7532
|
init_api();
|
|
7434
7533
|
function registerSendHandshakeCommand(root) {
|
|
7435
|
-
root.command("send-handshake").description("Send a handshake envelope to
|
|
7534
|
+
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("--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(
|
|
7436
7535
|
"--json",
|
|
7437
7536
|
"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.",
|
|
7438
7537
|
false
|
|
@@ -7441,46 +7540,44 @@ function registerSendHandshakeCommand(root) {
|
|
|
7441
7540
|
});
|
|
7442
7541
|
}
|
|
7443
7542
|
async function runSendHandshake(recipientDid, opts) {
|
|
7444
|
-
if (!(0, import_sdk25.isValidDid)(recipientDid)) {
|
|
7445
|
-
throw new Error(`send-handshake: <recipient-did> must be a valid did:arp identifier (base58btc-encoded 32-byte Ed25519 pubkey) (got '${recipientDid}')`);
|
|
7446
|
-
}
|
|
7447
7543
|
if (opts.verbose && opts.json) {
|
|
7448
7544
|
throw new Error(
|
|
7449
7545
|
"send-handshake: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds envelope + response dumps that would break `--json | jq`."
|
|
7450
7546
|
);
|
|
7451
7547
|
}
|
|
7548
|
+
recipientDid = await resolveRecipient(opts.server, "send-handshake", recipientDid, { json: opts.json });
|
|
7452
7549
|
const ttlSeconds = parseTtl3(opts.ttl);
|
|
7453
7550
|
const api = new ArpApiClient(opts.server);
|
|
7454
|
-
progress(opts.json,
|
|
7551
|
+
progress(opts.json, import_chalk30.default.dim(`Server: ${api.serverUrl}`));
|
|
7455
7552
|
const sender = resolveSenderAgent("send-handshake", opts.server, opts.fromDid);
|
|
7456
|
-
progress(opts.json,
|
|
7457
|
-
progress(opts.json,
|
|
7553
|
+
progress(opts.json, import_chalk30.default.dim(`Sender: ${sender.did}`));
|
|
7554
|
+
progress(opts.json, import_chalk30.default.dim(`Recipient: ${recipientDid}`));
|
|
7458
7555
|
const content = {};
|
|
7459
7556
|
if (opts.greeting) content.greeting = opts.greeting;
|
|
7460
7557
|
if (opts.intent) content.intent = opts.intent;
|
|
7461
7558
|
const body = { type: "handshake", content };
|
|
7462
7559
|
const nextSequence = (sender.lastSenderSequence ?? 0) + 1;
|
|
7463
7560
|
const protectedBlock = {
|
|
7464
|
-
protocol_version:
|
|
7465
|
-
purpose:
|
|
7466
|
-
message_id: (0,
|
|
7561
|
+
protocol_version: import_sdk28.CURRENT_PROTOCOL_VERSION,
|
|
7562
|
+
purpose: import_sdk28.Purpose.ENVELOPE,
|
|
7563
|
+
message_id: (0, import_sdk28.uuidV4)(),
|
|
7467
7564
|
sender_did: sender.did,
|
|
7468
7565
|
recipient_did: recipientDid,
|
|
7469
7566
|
relationship_id: null,
|
|
7470
7567
|
sender_sequence: nextSequence,
|
|
7471
|
-
sender_nonce: (0,
|
|
7472
|
-
timestamp: (0,
|
|
7473
|
-
expires_at: (0,
|
|
7568
|
+
sender_nonce: (0, import_sdk28.senderNonce)(),
|
|
7569
|
+
timestamp: (0, import_sdk28.rfc3339)(),
|
|
7570
|
+
expires_at: (0, import_sdk28.expiresAt)(ttlSeconds),
|
|
7474
7571
|
delivery_id: null
|
|
7475
7572
|
};
|
|
7476
7573
|
const signer = makeSigner(sender);
|
|
7477
|
-
const envelope = (0,
|
|
7574
|
+
const envelope = (0, import_sdk28.signEnvelope)({
|
|
7478
7575
|
protected: protectedBlock,
|
|
7479
7576
|
body,
|
|
7480
7577
|
identitySecretKey: signer.identitySecretKey
|
|
7481
7578
|
});
|
|
7482
7579
|
if (opts.verbose) {
|
|
7483
|
-
console.log(
|
|
7580
|
+
console.log(import_chalk30.default.bold("\nEnvelope (pre-send):"));
|
|
7484
7581
|
console.log(formatJson(envelope));
|
|
7485
7582
|
}
|
|
7486
7583
|
const result = await api.ingest(envelope);
|
|
@@ -7500,23 +7597,23 @@ async function runSendHandshake(recipientDid, opts) {
|
|
|
7500
7597
|
});
|
|
7501
7598
|
return;
|
|
7502
7599
|
}
|
|
7503
|
-
console.log(
|
|
7504
|
-
console.log(`${
|
|
7505
|
-
console.log(`${
|
|
7506
|
-
console.log(`${
|
|
7507
|
-
console.log(`${
|
|
7508
|
-
console.log(`${
|
|
7509
|
-
console.log(`${
|
|
7600
|
+
console.log(import_chalk30.default.green("\nDelivered."));
|
|
7601
|
+
console.log(`${import_chalk30.default.bold("Event id")}: ${import_chalk30.default.cyan(result.eventId)}`);
|
|
7602
|
+
console.log(`${import_chalk30.default.bold("Relationship id")}: ${import_chalk30.default.cyan(result.relationshipId)}`);
|
|
7603
|
+
console.log(`${import_chalk30.default.bold("Chain index")}: ${import_chalk30.default.cyan(String(result.relationshipEventIndex))}`);
|
|
7604
|
+
console.log(`${import_chalk30.default.bold("Server timestamp")}: ${import_chalk30.default.cyan(result.serverTimestamp)}`);
|
|
7605
|
+
console.log(`${import_chalk30.default.bold("Signed message hash")}: ${import_chalk30.default.cyan(result.signedMessageHash)}`);
|
|
7606
|
+
console.log(`${import_chalk30.default.bold("Server event hash")}: ${import_chalk30.default.cyan(result.serverEventHash)}`);
|
|
7510
7607
|
if (result.prevServerEventHash) {
|
|
7511
|
-
console.log(`${
|
|
7608
|
+
console.log(`${import_chalk30.default.bold("Prev server event hash")}: ${import_chalk30.default.cyan(result.prevServerEventHash)}`);
|
|
7512
7609
|
} else {
|
|
7513
|
-
console.log(`${
|
|
7610
|
+
console.log(`${import_chalk30.default.bold("Prev server event hash")}: ${import_chalk30.default.dim("(null \u2014 first event of this relationship)")}`);
|
|
7514
7611
|
}
|
|
7515
7612
|
if (opts.verbose) {
|
|
7516
|
-
console.log(
|
|
7613
|
+
console.log(import_chalk30.default.bold("\nFull server response:"));
|
|
7517
7614
|
console.log(formatJson(result));
|
|
7518
7615
|
}
|
|
7519
|
-
console.log(
|
|
7616
|
+
console.log(import_chalk30.default.dim(`
|
|
7520
7617
|
Local sender_sequence advanced to ${nextSequence}.`));
|
|
7521
7618
|
}
|
|
7522
7619
|
function parseTtl3(raw) {
|
|
@@ -7529,10 +7626,10 @@ function parseTtl3(raw) {
|
|
|
7529
7626
|
}
|
|
7530
7627
|
|
|
7531
7628
|
// src/commands/send-handshake-response.ts
|
|
7532
|
-
var
|
|
7533
|
-
var
|
|
7629
|
+
var import_sdk29 = require("@heyanon-arp/sdk");
|
|
7630
|
+
var import_chalk31 = __toESM(require("chalk"));
|
|
7534
7631
|
init_api();
|
|
7535
|
-
var ALLOWED_DECISIONS = new Set(
|
|
7632
|
+
var ALLOWED_DECISIONS = new Set(import_sdk29.HANDSHAKE_DECISIONS);
|
|
7536
7633
|
function registerSendHandshakeResponseCommand(root) {
|
|
7537
7634
|
root.command("send-handshake-response").description("Accept or decline an inbound handshake from <recipient-did>. Server reuses the existing relationship row.").argument("<recipient-did>", "Recipient agent DID (did:arp:...) \u2014 the original handshake sender").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("--decision <s>", "REQUIRED: accept or decline").option("--notes <s>", "Optional notes included in body.content").option(
|
|
7538
7635
|
"--reason <code>",
|
|
@@ -7540,8 +7637,8 @@ function registerSendHandshakeResponseCommand(root) {
|
|
|
7540
7637
|
// We don't use commander's requiredOption because it
|
|
7541
7638
|
// would fire for the accept path too; validate manually
|
|
7542
7639
|
// after decision is parsed.
|
|
7543
|
-
`When --decision=decline: required reason code (one of: ${
|
|
7544
|
-
).option("--reason-detail <s>", "Optional free-text elaboration alongside --reason (max 512 chars).").option("--ttl <seconds>", `Envelope TTL in seconds (max ${
|
|
7640
|
+
`When --decision=decline: required reason code (one of: ${import_sdk29.DECLINE_REASONS.join(", ")}). Carried in body.content.reason.`
|
|
7641
|
+
).option("--reason-detail <s>", "Optional free-text elaboration alongside --reason (max 512 chars).").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk29.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(
|
|
7545
7642
|
"--json",
|
|
7546
7643
|
"Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, decision, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash, prevServerEventHash}; idempotent short-circuit adds {idempotent:true}). Prelude + banners move off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.",
|
|
7547
7644
|
false
|
|
@@ -7559,23 +7656,23 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7559
7656
|
"send-handshake-response: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds envelope + response dumps that would break `--json | jq`."
|
|
7560
7657
|
);
|
|
7561
7658
|
}
|
|
7562
|
-
if (!(0,
|
|
7659
|
+
if (!(0, import_sdk29.isValidDid)(recipientDid)) {
|
|
7563
7660
|
throw new Error(`send-handshake-response: <recipient-did> must be a valid did:arp identifier (base58btc-encoded 32-byte Ed25519 pubkey) (got '${recipientDid}')`);
|
|
7564
7661
|
}
|
|
7565
7662
|
const decision = parseDecision(opts.decision);
|
|
7566
7663
|
const ttlSeconds = parseTtl4(opts.ttl);
|
|
7567
7664
|
let declinePayload = null;
|
|
7568
|
-
if (decision ===
|
|
7665
|
+
if (decision === import_sdk29.HandshakeDecisions.DECLINE) {
|
|
7569
7666
|
const reason = parseDeclineReason("send-handshake-response", opts.reason);
|
|
7570
7667
|
const detail = parseReasonDetail("send-handshake-response", opts.reasonDetail);
|
|
7571
7668
|
declinePayload = detail ? { reason, reasonDetail: detail } : { reason };
|
|
7572
7669
|
}
|
|
7573
7670
|
const api = new ArpApiClient(opts.server);
|
|
7574
|
-
progress(opts.json,
|
|
7671
|
+
progress(opts.json, import_chalk31.default.dim(`Server: ${api.serverUrl}`));
|
|
7575
7672
|
const sender = resolveSenderAgent("send-handshake-response", opts.server, opts.fromDid);
|
|
7576
|
-
progress(opts.json,
|
|
7577
|
-
progress(opts.json,
|
|
7578
|
-
progress(opts.json,
|
|
7673
|
+
progress(opts.json, import_chalk31.default.dim(`Sender: ${sender.did}`));
|
|
7674
|
+
progress(opts.json, import_chalk31.default.dim(`Recipient: ${recipientDid}`));
|
|
7675
|
+
progress(opts.json, import_chalk31.default.dim(`Decision: ${decision}`));
|
|
7579
7676
|
const signer = makeSigner(sender);
|
|
7580
7677
|
if (!opts.force) {
|
|
7581
7678
|
try {
|
|
@@ -7605,13 +7702,13 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7605
7702
|
});
|
|
7606
7703
|
return;
|
|
7607
7704
|
}
|
|
7608
|
-
progress(opts.json,
|
|
7705
|
+
progress(opts.json, import_chalk31.default.yellow(`
|
|
7609
7706
|
[--idempotency] Relationship ${existing.relationshipId} with ${recipientDid} is already 'active'.`));
|
|
7610
7707
|
progress(
|
|
7611
7708
|
opts.json,
|
|
7612
|
-
|
|
7709
|
+
import_chalk31.default.dim(`A previous accept from this signer (event ${previousResponseFromMe.eventId}) landed successfully. Skipping re-send (use --force to override).`)
|
|
7613
7710
|
);
|
|
7614
|
-
progress(opts.json,
|
|
7711
|
+
progress(opts.json, import_chalk31.default.dim(`Last event index: ${existing.lastEventIndex}, last server event hash: ${existing.lastServerEventHash ?? "(none)"}`));
|
|
7615
7712
|
return;
|
|
7616
7713
|
}
|
|
7617
7714
|
throw new Error(
|
|
@@ -7622,7 +7719,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7622
7719
|
if (probeErr instanceof Error && /CLOSED|terminated|already 'active' from a previous ACCEPT|original initiator/i.test(probeErr.message)) {
|
|
7623
7720
|
throw probeErr;
|
|
7624
7721
|
}
|
|
7625
|
-
progress(opts.json,
|
|
7722
|
+
progress(opts.json, import_chalk31.default.dim(`(idempotency probe failed; proceeding anyway: ${probeErr.message})`));
|
|
7626
7723
|
}
|
|
7627
7724
|
}
|
|
7628
7725
|
const content = { decision };
|
|
@@ -7634,25 +7731,25 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7634
7731
|
const body = { type: "handshake_response", content };
|
|
7635
7732
|
const nextSequence = (sender.lastSenderSequence ?? 0) + 1;
|
|
7636
7733
|
const protectedBlock = {
|
|
7637
|
-
protocol_version:
|
|
7638
|
-
purpose:
|
|
7639
|
-
message_id: (0,
|
|
7734
|
+
protocol_version: import_sdk29.CURRENT_PROTOCOL_VERSION,
|
|
7735
|
+
purpose: import_sdk29.Purpose.ENVELOPE,
|
|
7736
|
+
message_id: (0, import_sdk29.uuidV4)(),
|
|
7640
7737
|
sender_did: sender.did,
|
|
7641
7738
|
recipient_did: recipientDid,
|
|
7642
7739
|
relationship_id: null,
|
|
7643
7740
|
sender_sequence: nextSequence,
|
|
7644
|
-
sender_nonce: (0,
|
|
7645
|
-
timestamp: (0,
|
|
7646
|
-
expires_at: (0,
|
|
7741
|
+
sender_nonce: (0, import_sdk29.senderNonce)(),
|
|
7742
|
+
timestamp: (0, import_sdk29.rfc3339)(),
|
|
7743
|
+
expires_at: (0, import_sdk29.expiresAt)(ttlSeconds),
|
|
7647
7744
|
delivery_id: null
|
|
7648
7745
|
};
|
|
7649
|
-
const envelope = (0,
|
|
7746
|
+
const envelope = (0, import_sdk29.signEnvelope)({
|
|
7650
7747
|
protected: protectedBlock,
|
|
7651
7748
|
body,
|
|
7652
7749
|
identitySecretKey: signer.identitySecretKey
|
|
7653
7750
|
});
|
|
7654
7751
|
if (opts.verbose) {
|
|
7655
|
-
console.log(
|
|
7752
|
+
console.log(import_chalk31.default.bold("\nEnvelope (pre-send):"));
|
|
7656
7753
|
console.log(formatJson(envelope));
|
|
7657
7754
|
}
|
|
7658
7755
|
const result = await api.ingest(envelope);
|
|
@@ -7673,23 +7770,23 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7673
7770
|
});
|
|
7674
7771
|
return;
|
|
7675
7772
|
}
|
|
7676
|
-
console.log(
|
|
7677
|
-
console.log(`${
|
|
7678
|
-
console.log(`${
|
|
7679
|
-
console.log(`${
|
|
7680
|
-
console.log(`${
|
|
7681
|
-
console.log(`${
|
|
7682
|
-
console.log(`${
|
|
7773
|
+
console.log(import_chalk31.default.green("\nDelivered."));
|
|
7774
|
+
console.log(`${import_chalk31.default.bold("Event id")}: ${import_chalk31.default.cyan(result.eventId)}`);
|
|
7775
|
+
console.log(`${import_chalk31.default.bold("Relationship id")}: ${import_chalk31.default.cyan(result.relationshipId)}`);
|
|
7776
|
+
console.log(`${import_chalk31.default.bold("Chain index")}: ${import_chalk31.default.cyan(String(result.relationshipEventIndex))}`);
|
|
7777
|
+
console.log(`${import_chalk31.default.bold("Server timestamp")}: ${import_chalk31.default.cyan(result.serverTimestamp)}`);
|
|
7778
|
+
console.log(`${import_chalk31.default.bold("Signed message hash")}: ${import_chalk31.default.cyan(result.signedMessageHash)}`);
|
|
7779
|
+
console.log(`${import_chalk31.default.bold("Server event hash")}: ${import_chalk31.default.cyan(result.serverEventHash)}`);
|
|
7683
7780
|
if (result.prevServerEventHash) {
|
|
7684
|
-
console.log(`${
|
|
7781
|
+
console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.cyan(result.prevServerEventHash)}`);
|
|
7685
7782
|
} else {
|
|
7686
|
-
console.log(`${
|
|
7783
|
+
console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.dim("(null \u2014 first event of this relationship)")}`);
|
|
7687
7784
|
}
|
|
7688
7785
|
if (opts.verbose) {
|
|
7689
|
-
console.log(
|
|
7786
|
+
console.log(import_chalk31.default.bold("\nFull server response:"));
|
|
7690
7787
|
console.log(formatJson(result));
|
|
7691
7788
|
}
|
|
7692
|
-
console.log(
|
|
7789
|
+
console.log(import_chalk31.default.dim(`
|
|
7693
7790
|
Local sender_sequence advanced to ${nextSequence}.`));
|
|
7694
7791
|
}
|
|
7695
7792
|
function parseDecision(raw) {
|
|
@@ -7711,8 +7808,8 @@ function parseTtl4(raw) {
|
|
|
7711
7808
|
}
|
|
7712
7809
|
function classifyIdempotencyOutcome(decision, existing) {
|
|
7713
7810
|
if (!existing) return { kind: "proceed" };
|
|
7714
|
-
if (existing.state ===
|
|
7715
|
-
if (decision ===
|
|
7811
|
+
if (existing.state === import_sdk29.RelationshipStates.ACTIVE) {
|
|
7812
|
+
if (decision === import_sdk29.HandshakeDecisions.DECLINE) {
|
|
7716
7813
|
return {
|
|
7717
7814
|
kind: "error",
|
|
7718
7815
|
message: `send-handshake-response: relationship ${existing.relationshipId} is already 'active' from a previous ACCEPT. A decline cannot reverse that \u2014 the active relationship is now under FSM control. If you want to terminate, close the relationship explicitly; pass --force to ignore this check and send the decline (which the server will reject with DOM_INVALID_TRANSITION).`
|
|
@@ -7720,7 +7817,7 @@ function classifyIdempotencyOutcome(decision, existing) {
|
|
|
7720
7817
|
}
|
|
7721
7818
|
return { kind: "short-circuit" };
|
|
7722
7819
|
}
|
|
7723
|
-
if (existing.state ===
|
|
7820
|
+
if (existing.state === import_sdk29.RelationshipStates.CLOSED) {
|
|
7724
7821
|
return {
|
|
7725
7822
|
kind: "error",
|
|
7726
7823
|
message: `send-handshake-response: relationship ${existing.relationshipId} is CLOSED. Cannot respond to handshake on a terminated relationship \u2014 start a fresh handshake instead.`
|
|
@@ -7740,7 +7837,7 @@ async function findExistingRelationship(api, signer, senderDid, recipientDid) {
|
|
|
7740
7837
|
}
|
|
7741
7838
|
|
|
7742
7839
|
// src/commands/watch.ts
|
|
7743
|
-
var
|
|
7840
|
+
var import_chalk32 = __toESM(require("chalk"));
|
|
7744
7841
|
init_api();
|
|
7745
7842
|
function registerWatchCommand(root) {
|
|
7746
7843
|
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("--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) => {
|
|
@@ -7751,9 +7848,9 @@ async function runWatch(relationshipId, opts) {
|
|
|
7751
7848
|
const local = resolveSenderAgent("watch", opts.server, opts.fromDid);
|
|
7752
7849
|
const api = new ArpApiClient(opts.server);
|
|
7753
7850
|
if (!opts.json) {
|
|
7754
|
-
console.log(
|
|
7755
|
-
console.log(
|
|
7756
|
-
console.log(
|
|
7851
|
+
console.log(import_chalk32.default.dim(`Server: ${api.serverUrl}`));
|
|
7852
|
+
console.log(import_chalk32.default.dim(`Signer: ${local.did}`));
|
|
7853
|
+
console.log(import_chalk32.default.dim(`Watching: ${relationshipId}`));
|
|
7757
7854
|
}
|
|
7758
7855
|
const controller = new AbortController();
|
|
7759
7856
|
let userAborted = false;
|
|
@@ -7772,7 +7869,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7772
7869
|
}
|
|
7773
7870
|
if (event.type === "heartbeat") continue;
|
|
7774
7871
|
if (event.type === "connected") {
|
|
7775
|
-
console.log(
|
|
7872
|
+
console.log(import_chalk32.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
|
|
7776
7873
|
continue;
|
|
7777
7874
|
}
|
|
7778
7875
|
if (event.type === "envelope") {
|
|
@@ -7786,7 +7883,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7786
7883
|
}
|
|
7787
7884
|
continue;
|
|
7788
7885
|
}
|
|
7789
|
-
console.log(
|
|
7886
|
+
console.log(import_chalk32.default.dim(`(unknown event: ${event.type})`));
|
|
7790
7887
|
}
|
|
7791
7888
|
if (!userAborted) {
|
|
7792
7889
|
throw new Error(`watch ${relationshipId}: stream ended unexpectedly (server may have restarted, or the change stream errored). Re-run to reconnect.`);
|
|
@@ -7794,7 +7891,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7794
7891
|
} catch (err) {
|
|
7795
7892
|
const name = err.name;
|
|
7796
7893
|
if (name === "AbortError" || userAborted) {
|
|
7797
|
-
if (!opts.json) console.log(
|
|
7894
|
+
if (!opts.json) console.log(import_chalk32.default.dim("\nstream closed."));
|
|
7798
7895
|
return;
|
|
7799
7896
|
}
|
|
7800
7897
|
throw err;
|
|
@@ -7808,21 +7905,21 @@ function formatWatchLine(ev, selfDid, opts = {}) {
|
|
|
7808
7905
|
const type = ev.type.padEnd(20);
|
|
7809
7906
|
const direction = directionLabel2(ev, selfDid, opts);
|
|
7810
7907
|
const hash = opts.fullIds ? ev.serverEventHash : hashHead4(ev.serverEventHash);
|
|
7811
|
-
return `${
|
|
7908
|
+
return `${import_chalk32.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk32.default.cyan(hash)}`;
|
|
7812
7909
|
}
|
|
7813
7910
|
function directionLabel2(ev, selfDid, opts = {}) {
|
|
7814
7911
|
const senderHead = opts.fullIds ? ev.senderDid : didHead4(ev.senderDid);
|
|
7815
7912
|
const recipientHead = opts.fullIds ? ev.recipientDid : didHead4(ev.recipientDid);
|
|
7816
|
-
if (ev.senderDid === selfDid) return `${
|
|
7817
|
-
if (ev.recipientDid === selfDid) return `${
|
|
7818
|
-
return `${
|
|
7913
|
+
if (ev.senderDid === selfDid) return `${import_chalk32.default.bold("me")} \u2192 ${import_chalk32.default.dim(recipientHead)}`;
|
|
7914
|
+
if (ev.recipientDid === selfDid) return `${import_chalk32.default.dim(senderHead)} \u2192 ${import_chalk32.default.bold("me")}`;
|
|
7915
|
+
return `${import_chalk32.default.dim(senderHead)} \u2192 ${import_chalk32.default.dim(recipientHead)}`;
|
|
7819
7916
|
}
|
|
7820
7917
|
function didHead4(did) {
|
|
7821
7918
|
if (did.length <= 20) return did;
|
|
7822
7919
|
return `${did.slice(0, 20)}...`;
|
|
7823
7920
|
}
|
|
7824
7921
|
function hashHead4(hash) {
|
|
7825
|
-
if (!hash) return
|
|
7922
|
+
if (!hash) return import_chalk32.default.dim("(none)");
|
|
7826
7923
|
if (hash.length <= 14) return hash;
|
|
7827
7924
|
return `${hash.slice(0, 14)}...`;
|
|
7828
7925
|
}
|
|
@@ -7834,7 +7931,7 @@ function formatClock(iso) {
|
|
|
7834
7931
|
}
|
|
7835
7932
|
|
|
7836
7933
|
// src/commands/whoami.ts
|
|
7837
|
-
var
|
|
7934
|
+
var import_chalk33 = __toESM(require("chalk"));
|
|
7838
7935
|
init_api();
|
|
7839
7936
|
function registerWhoamiCommand(root) {
|
|
7840
7937
|
root.command("whoami").description(
|
|
@@ -7864,12 +7961,12 @@ function registerWhoamiCommand(root) {
|
|
|
7864
7961
|
if (opts.json) {
|
|
7865
7962
|
console.log(formatJson({ ...localJson, account: credential ? { wallet: credential.wallet } : null }));
|
|
7866
7963
|
} else {
|
|
7867
|
-
console.log(
|
|
7868
|
-
console.log(` DID: ${
|
|
7869
|
-
console.log(` Settlement pubkey: ${
|
|
7870
|
-
console.log(` Identity pubkey: ${
|
|
7964
|
+
console.log(import_chalk33.default.bold("Local agent:"));
|
|
7965
|
+
console.log(` DID: ${import_chalk33.default.cyan(local.did)}`);
|
|
7966
|
+
console.log(` Settlement pubkey: ${import_chalk33.default.cyan(local.settlementPublicKeyB58)}`);
|
|
7967
|
+
console.log(` Identity pubkey: ${import_chalk33.default.cyan(local.identityPublicKeyB58)}`);
|
|
7871
7968
|
if (local.name) console.log(` Name: ${local.name}`);
|
|
7872
|
-
console.log(` Account: ${credential ?
|
|
7969
|
+
console.log(` Account: ${credential ? import_chalk33.default.cyan(credential.wallet) : import_chalk33.default.dim("not logged in (heyarp login)")}`);
|
|
7873
7970
|
}
|
|
7874
7971
|
return;
|
|
7875
7972
|
}
|
|
@@ -7887,19 +7984,19 @@ function registerWhoamiCommand(root) {
|
|
|
7887
7984
|
if (opts.json) {
|
|
7888
7985
|
console.log(formatJson({ local: localJson, account, server: agent }));
|
|
7889
7986
|
} else {
|
|
7890
|
-
console.log(
|
|
7891
|
-
console.log(
|
|
7892
|
-
console.log(` DID: ${
|
|
7893
|
-
console.log(` Settlement pubkey: ${
|
|
7894
|
-
console.log(` Identity pubkey: ${
|
|
7895
|
-
console.log(
|
|
7987
|
+
console.log(import_chalk33.default.dim(`Server: ${api.serverUrl}`));
|
|
7988
|
+
console.log(import_chalk33.default.bold("\nLocal agent:"));
|
|
7989
|
+
console.log(` DID: ${import_chalk33.default.cyan(local.did)}`);
|
|
7990
|
+
console.log(` Settlement pubkey: ${import_chalk33.default.cyan(local.settlementPublicKeyB58)}`);
|
|
7991
|
+
console.log(` Identity pubkey: ${import_chalk33.default.cyan(local.identityPublicKeyB58)}`);
|
|
7992
|
+
console.log(import_chalk33.default.bold("\nAccount:"));
|
|
7896
7993
|
if (account) {
|
|
7897
|
-
console.log(` Wallet: ${
|
|
7994
|
+
console.log(` Wallet: ${import_chalk33.default.cyan(account.wallet)}`);
|
|
7898
7995
|
console.log(` Agents registered: ${account.agentCount}`);
|
|
7899
7996
|
} else {
|
|
7900
|
-
console.log(` ${
|
|
7997
|
+
console.log(` ${import_chalk33.default.dim("not logged in (heyarp login)")}`);
|
|
7901
7998
|
}
|
|
7902
|
-
console.log(
|
|
7999
|
+
console.log(import_chalk33.default.bold("\nServer profile:"));
|
|
7903
8000
|
console.log(formatJson(agent));
|
|
7904
8001
|
}
|
|
7905
8002
|
} catch (err) {
|
|
@@ -7909,9 +8006,49 @@ function registerWhoamiCommand(root) {
|
|
|
7909
8006
|
});
|
|
7910
8007
|
}
|
|
7911
8008
|
|
|
8009
|
+
// src/commands/whois.ts
|
|
8010
|
+
var import_sdk30 = require("@heyanon-arp/sdk");
|
|
8011
|
+
var import_chalk34 = __toESM(require("chalk"));
|
|
8012
|
+
init_api();
|
|
8013
|
+
function registerWhoisCommand(root) {
|
|
8014
|
+
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) => {
|
|
8015
|
+
const api = new ArpApiClient(opts.server);
|
|
8016
|
+
progress(opts.json, import_chalk34.default.dim(`Server: ${api.serverUrl}`));
|
|
8017
|
+
const profile = await resolveProfile(api, input);
|
|
8018
|
+
if (opts.json) {
|
|
8019
|
+
jsonOut(profile);
|
|
8020
|
+
return;
|
|
8021
|
+
}
|
|
8022
|
+
printProfile(profile);
|
|
8023
|
+
});
|
|
8024
|
+
}
|
|
8025
|
+
async function resolveProfile(api, input) {
|
|
8026
|
+
if (input.startsWith("did:arp:")) {
|
|
8027
|
+
if (!(0, import_sdk30.isValidDid)(input)) {
|
|
8028
|
+
throw new Error(`whois: '${input}' starts with did:arp: but is not a valid DID (base58btc-encoded 32-byte Ed25519 pubkey).`);
|
|
8029
|
+
}
|
|
8030
|
+
return api.discoverProfile(input);
|
|
8031
|
+
}
|
|
8032
|
+
const name = (0, import_sdk30.normalizeName)(input);
|
|
8033
|
+
if (!(0, import_sdk30.isValidAgentName)(name)) {
|
|
8034
|
+
throw new Error(`whois: '${input}' is neither a DID (did:arp:...) nor a valid agent name (lowercase a-z0-9_, 3-32 chars).`);
|
|
8035
|
+
}
|
|
8036
|
+
return api.discoverByName(name);
|
|
8037
|
+
}
|
|
8038
|
+
function printProfile(p) {
|
|
8039
|
+
console.log(`${import_chalk34.default.bold("Name")}: ${import_chalk34.default.cyan(p.name ?? "(unnamed)")}`);
|
|
8040
|
+
console.log(`${import_chalk34.default.bold("DID")}: ${import_chalk34.default.cyan(p.did)}`);
|
|
8041
|
+
if (p.description) console.log(`${import_chalk34.default.bold("Description")}: ${p.description}`);
|
|
8042
|
+
if (p.tags.length > 0) console.log(`${import_chalk34.default.bold("Tags")}: ${p.tags.join(", ")}`);
|
|
8043
|
+
console.log(`${import_chalk34.default.bold("Registered")}: ${p.registeredAt}`);
|
|
8044
|
+
const rep = p.reputation;
|
|
8045
|
+
console.log(`${import_chalk34.default.bold("Reputation")}: composite ${rep.scores.composite}/100${rep.computed ? "" : import_chalk34.default.dim(" (cold-start \u2014 no settled cycles yet)")}`);
|
|
8046
|
+
console.log(`${import_chalk34.default.bold("Online")}: ${p.liveness.online ? import_chalk34.default.green("yes") : import_chalk34.default.dim("no")}`);
|
|
8047
|
+
}
|
|
8048
|
+
|
|
7912
8049
|
// src/commands/work.ts
|
|
7913
|
-
var
|
|
7914
|
-
var
|
|
8050
|
+
var import_sdk31 = require("@heyanon-arp/sdk");
|
|
8051
|
+
var import_chalk35 = __toESM(require("chalk"));
|
|
7915
8052
|
init_api();
|
|
7916
8053
|
function registerWorkCommands(root) {
|
|
7917
8054
|
const cmd = root.command("work").description("Work envelopes inside an ACCEPTED delegation: request / respond");
|
|
@@ -7919,13 +8056,13 @@ function registerWorkCommands(root) {
|
|
|
7919
8056
|
registerRespond(cmd);
|
|
7920
8057
|
}
|
|
7921
8058
|
function registerRequest(parent) {
|
|
7922
|
-
parent.command("request").description("Send a work_request to <recipient-did> under <delegation-id> (must be ACCEPTED).").argument("<recipient
|
|
8059
|
+
parent.command("request").description("Send a work_request to <recipient-did> under <delegation-id> (must be ACCEPTED).").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (the payee \u2014 the OTHER side of the delegation pair)").argument("<delegation-id>", "Parent delegation id (UUID, must be 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("--request-id <id>", "Override the auto-generated request id (must be unique within the delegation)").option(
|
|
7923
8060
|
"--params <json>",
|
|
7924
8061
|
"JSON object payload as a literal string. Defaults to {}. Mutually exclusive with --params-file. Brittle against shell quoting \u2014 prefer --params-file for non-trivial bodies."
|
|
7925
8062
|
).option(
|
|
7926
8063
|
"--params-file <path>",
|
|
7927
8064
|
"Read the JSON payload from a file. Mutually exclusive with --params. Use this for any payload large or quote-heavy enough that `--params '{...}'` would fight your shell."
|
|
7928
|
-
).option("--ttl <seconds>", `Envelope TTL in seconds (max ${
|
|
8065
|
+
).option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk31.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(
|
|
7929
8066
|
"--json",
|
|
7930
8067
|
'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"work_request", requestId, delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + reply hints move to stderr; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
|
|
7931
8068
|
false
|
|
@@ -7939,7 +8076,7 @@ async function runRequest(recipientDid, delegationId, opts) {
|
|
|
7939
8076
|
"work request: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds dumps that would break `--json | jq`."
|
|
7940
8077
|
);
|
|
7941
8078
|
}
|
|
7942
|
-
|
|
8079
|
+
recipientDid = await resolveRecipient(opts.server, "work request", recipientDid, { json: opts.json });
|
|
7943
8080
|
delegationId = requireUuidNormalised3("work request", delegationId, "<delegation-id>");
|
|
7944
8081
|
const ttlSeconds = parseTtl5("work request", opts.ttl);
|
|
7945
8082
|
const params = parseParamsInput("work request", opts);
|
|
@@ -7952,11 +8089,11 @@ async function runRequest(recipientDid, delegationId, opts) {
|
|
|
7952
8089
|
params
|
|
7953
8090
|
};
|
|
7954
8091
|
const body = { type: "work_request", content };
|
|
7955
|
-
progress(opts.json,
|
|
7956
|
-
progress(opts.json,
|
|
7957
|
-
progress(opts.json,
|
|
7958
|
-
progress(opts.json,
|
|
7959
|
-
progress(opts.json,
|
|
8092
|
+
progress(opts.json, import_chalk35.default.dim(`Server: ${api.serverUrl}`));
|
|
8093
|
+
progress(opts.json, import_chalk35.default.dim(`Sender: ${sender.did}`));
|
|
8094
|
+
progress(opts.json, import_chalk35.default.dim(`Recipient: ${recipientDid}`));
|
|
8095
|
+
progress(opts.json, import_chalk35.default.dim(`Delegation: ${delegationId}`));
|
|
8096
|
+
progress(opts.json, import_chalk35.default.dim(`Request id: ${requestId}`));
|
|
7960
8097
|
const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
7961
8098
|
if (opts.json) {
|
|
7962
8099
|
jsonOut({
|
|
@@ -7973,10 +8110,10 @@ async function runRequest(recipientDid, delegationId, opts) {
|
|
|
7973
8110
|
});
|
|
7974
8111
|
} else {
|
|
7975
8112
|
printIngestResult3(result);
|
|
7976
|
-
console.log(
|
|
8113
|
+
console.log(import_chalk35.default.dim(`
|
|
7977
8114
|
The payee can reply with:`));
|
|
7978
|
-
console.log(
|
|
7979
|
-
console.log(
|
|
8115
|
+
console.log(import_chalk35.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
|
|
8116
|
+
console.log(import_chalk35.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
|
|
7980
8117
|
}
|
|
7981
8118
|
}
|
|
7982
8119
|
function registerRespond(parent) {
|
|
@@ -8011,13 +8148,13 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
|
|
|
8011
8148
|
...responsePayload
|
|
8012
8149
|
};
|
|
8013
8150
|
const body = { type: "work_response", content };
|
|
8014
|
-
progress(opts.json,
|
|
8015
|
-
progress(opts.json,
|
|
8016
|
-
progress(opts.json,
|
|
8017
|
-
progress(opts.json,
|
|
8018
|
-
progress(opts.json,
|
|
8019
|
-
progress(opts.json,
|
|
8020
|
-
progress(opts.json,
|
|
8151
|
+
progress(opts.json, import_chalk35.default.dim(`Server: ${api.serverUrl}`));
|
|
8152
|
+
progress(opts.json, import_chalk35.default.dim(`Sender: ${sender.did}`));
|
|
8153
|
+
progress(opts.json, import_chalk35.default.dim(`Recipient: ${recipientDid}`));
|
|
8154
|
+
progress(opts.json, import_chalk35.default.dim(`Relationship: ${relationshipId}`));
|
|
8155
|
+
progress(opts.json, import_chalk35.default.dim(`Delegation: ${delegationId}`));
|
|
8156
|
+
progress(opts.json, import_chalk35.default.dim(`Request id: ${requestId}`));
|
|
8157
|
+
progress(opts.json, import_chalk35.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
|
|
8021
8158
|
const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
8022
8159
|
if (opts.json) {
|
|
8023
8160
|
jsonOut({
|
|
@@ -8039,26 +8176,26 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
|
|
|
8039
8176
|
async function sendWorkEnvelope(args) {
|
|
8040
8177
|
const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
|
|
8041
8178
|
const protectedBlock = {
|
|
8042
|
-
protocol_version:
|
|
8043
|
-
purpose:
|
|
8044
|
-
message_id: (0,
|
|
8179
|
+
protocol_version: import_sdk31.CURRENT_PROTOCOL_VERSION,
|
|
8180
|
+
purpose: import_sdk31.Purpose.ENVELOPE,
|
|
8181
|
+
message_id: (0, import_sdk31.uuidV4)(),
|
|
8045
8182
|
sender_did: args.sender.did,
|
|
8046
8183
|
recipient_did: args.recipientDid,
|
|
8047
8184
|
relationship_id: null,
|
|
8048
8185
|
sender_sequence: nextSequence,
|
|
8049
|
-
sender_nonce: (0,
|
|
8050
|
-
timestamp: (0,
|
|
8051
|
-
expires_at: (0,
|
|
8186
|
+
sender_nonce: (0, import_sdk31.senderNonce)(),
|
|
8187
|
+
timestamp: (0, import_sdk31.rfc3339)(),
|
|
8188
|
+
expires_at: (0, import_sdk31.expiresAt)(args.ttlSeconds),
|
|
8052
8189
|
delivery_id: null
|
|
8053
8190
|
};
|
|
8054
8191
|
const signer = makeSigner(args.sender);
|
|
8055
|
-
const envelope = (0,
|
|
8192
|
+
const envelope = (0, import_sdk31.signEnvelope)({
|
|
8056
8193
|
protected: protectedBlock,
|
|
8057
8194
|
body: args.body,
|
|
8058
8195
|
identitySecretKey: signer.identitySecretKey
|
|
8059
8196
|
});
|
|
8060
8197
|
if (args.verbose) {
|
|
8061
|
-
console.log(
|
|
8198
|
+
console.log(import_chalk35.default.bold("\nEnvelope (pre-send):"));
|
|
8062
8199
|
console.log(formatJson(envelope));
|
|
8063
8200
|
}
|
|
8064
8201
|
try {
|
|
@@ -8066,7 +8203,7 @@ async function sendWorkEnvelope(args) {
|
|
|
8066
8203
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
8067
8204
|
return result;
|
|
8068
8205
|
} catch (err) {
|
|
8069
|
-
if (err instanceof ApiError && (0,
|
|
8206
|
+
if (err instanceof ApiError && (0, import_sdk31.isPostCommitErrorCode)(err.payload.code)) {
|
|
8070
8207
|
updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
|
|
8071
8208
|
}
|
|
8072
8209
|
throw err;
|
|
@@ -8078,7 +8215,7 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
|
|
|
8078
8215
|
const page = await api.listWorkLogs(args.relationshipId, signer, { delegationId: args.delegationId, limit: 100, after });
|
|
8079
8216
|
const row = page.find((w) => w.requestId === args.requestId);
|
|
8080
8217
|
if (row) {
|
|
8081
|
-
if (row.state !==
|
|
8218
|
+
if (row.state !== import_sdk31.WorkLogStates.REQUESTED) {
|
|
8082
8219
|
throw new Error(
|
|
8083
8220
|
`${cmdName}: work_request ${args.requestId} for delegation ${args.delegationId} is already in state '${row.state}' \u2014 only requests in state 'requested' can be responded to.`
|
|
8084
8221
|
);
|
|
@@ -8098,12 +8235,12 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
|
|
|
8098
8235
|
);
|
|
8099
8236
|
}
|
|
8100
8237
|
function printIngestResult3(result) {
|
|
8101
|
-
console.log(
|
|
8102
|
-
console.log(`${
|
|
8103
|
-
console.log(`${
|
|
8104
|
-
console.log(`${
|
|
8105
|
-
console.log(`${
|
|
8106
|
-
console.log(`${
|
|
8238
|
+
console.log(import_chalk35.default.green("\nDelivered."));
|
|
8239
|
+
console.log(`${import_chalk35.default.bold("Event id")}: ${import_chalk35.default.cyan(result.eventId)}`);
|
|
8240
|
+
console.log(`${import_chalk35.default.bold("Relationship id")}: ${import_chalk35.default.cyan(result.relationshipId)}`);
|
|
8241
|
+
console.log(`${import_chalk35.default.bold("Chain index")}: ${import_chalk35.default.cyan(String(result.relationshipEventIndex))}`);
|
|
8242
|
+
console.log(`${import_chalk35.default.bold("Server timestamp")}: ${import_chalk35.default.cyan(result.serverTimestamp)}`);
|
|
8243
|
+
console.log(`${import_chalk35.default.bold("Server event hash")}: ${import_chalk35.default.cyan(result.serverEventHash)}`);
|
|
8107
8244
|
}
|
|
8108
8245
|
function parseJsonObject(cmdName, flagName, raw) {
|
|
8109
8246
|
let parsed;
|
|
@@ -8195,7 +8332,7 @@ function parseTtl5(cmdName, raw) {
|
|
|
8195
8332
|
}
|
|
8196
8333
|
function parseRequestId(cmdName, raw) {
|
|
8197
8334
|
if (raw === void 0 || raw === "") {
|
|
8198
|
-
return (0,
|
|
8335
|
+
return (0, import_sdk31.uuidV4)();
|
|
8199
8336
|
}
|
|
8200
8337
|
if (raw.length === 0) {
|
|
8201
8338
|
throw new Error(`${cmdName}: --request-id must be a non-empty string`);
|
|
@@ -8209,17 +8346,12 @@ function requireUuidNormalised3(cmdName, raw, label) {
|
|
|
8209
8346
|
function requireUuid4(cmdName, raw, label) {
|
|
8210
8347
|
requireUuid(cmdName, raw, label);
|
|
8211
8348
|
}
|
|
8212
|
-
function requireDid3(cmdName, did, label) {
|
|
8213
|
-
if (typeof did !== "string" || !did.startsWith("did:arp:") || did.length <= "did:arp:".length) {
|
|
8214
|
-
throw new Error(`${cmdName}: ${label} must look like 'did:arp:...' (got '${did}')`);
|
|
8215
|
-
}
|
|
8216
|
-
}
|
|
8217
8349
|
|
|
8218
8350
|
// src/commands/work-list.ts
|
|
8219
|
-
var
|
|
8220
|
-
var
|
|
8351
|
+
var import_sdk32 = require("@heyanon-arp/sdk");
|
|
8352
|
+
var import_chalk36 = __toESM(require("chalk"));
|
|
8221
8353
|
init_api();
|
|
8222
|
-
var ALLOWED_STATES3 = new Set(
|
|
8354
|
+
var ALLOWED_STATES3 = new Set(import_sdk32.WORK_LOG_STATES);
|
|
8223
8355
|
function registerWorkListCommand(root) {
|
|
8224
8356
|
root.command("work-list").description("List work-log rows for a relationship (one row per (delegationId, requestId), oldest-first)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--state <s>", "Filter by exact state (requested|responded)").option("--delegation-id <uuid>", "Narrow to work-logs operating under a specific delegation id").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(
|
|
8225
8357
|
"--verbose",
|
|
@@ -8244,9 +8376,9 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8244
8376
|
const api = new ArpApiClient(opts.server);
|
|
8245
8377
|
const sender = resolveSenderAgent("work-list", opts.server, opts.fromDid);
|
|
8246
8378
|
if (!opts.json) {
|
|
8247
|
-
console.log(
|
|
8248
|
-
console.log(
|
|
8249
|
-
console.log(
|
|
8379
|
+
console.log(import_chalk36.default.dim(`Server: ${api.serverUrl}`));
|
|
8380
|
+
console.log(import_chalk36.default.dim(`Signer: ${sender.did}`));
|
|
8381
|
+
console.log(import_chalk36.default.dim(`Relationship: ${relationshipId}`));
|
|
8250
8382
|
}
|
|
8251
8383
|
const query = { limit };
|
|
8252
8384
|
if (state) query.state = state;
|
|
@@ -8259,7 +8391,7 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8259
8391
|
return;
|
|
8260
8392
|
}
|
|
8261
8393
|
if (rows.length === 0) {
|
|
8262
|
-
console.log(
|
|
8394
|
+
console.log(import_chalk36.default.dim("\n(no work-logs for this relationship)"));
|
|
8263
8395
|
return;
|
|
8264
8396
|
}
|
|
8265
8397
|
console.log("");
|
|
@@ -8276,36 +8408,36 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8276
8408
|
}));
|
|
8277
8409
|
}
|
|
8278
8410
|
const lastId = rows[rows.length - 1].id;
|
|
8279
|
-
console.log(
|
|
8411
|
+
console.log(import_chalk36.default.dim(`
|
|
8280
8412
|
${rows.length} work-log row(s). Paginate with --after ${lastId}.`));
|
|
8281
8413
|
}
|
|
8282
8414
|
function formatWorkLogLine(w, selfDid, opts = {}) {
|
|
8283
8415
|
const delegationPart = opts.fullIds ? w.delegationId : idHead3(w.delegationId);
|
|
8284
8416
|
const requestPart = opts.fullIds ? w.requestId : truncate3(w.requestId, 16);
|
|
8285
|
-
const id =
|
|
8417
|
+
const id = import_chalk36.default.bold(`${delegationPart}/${requestPart}`);
|
|
8286
8418
|
const state = colorState2(w.state).padEnd(stateColumnWidth2());
|
|
8287
8419
|
const peerCallerHead = opts.fullIds ? w.callerDid : didHead5(w.callerDid);
|
|
8288
8420
|
const peerPayeeHead = opts.fullIds ? w.payeeDid : didHead5(w.payeeDid);
|
|
8289
|
-
const direction = w.callerDid === selfDid ? `${
|
|
8421
|
+
const direction = w.callerDid === selfDid ? `${import_chalk36.default.bold("me")} \u2192 ${import_chalk36.default.dim(peerPayeeHead)}` : `${import_chalk36.default.dim(peerCallerHead)} \u2192 ${import_chalk36.default.bold("me")}`;
|
|
8290
8422
|
const outcome = formatOutcome(w);
|
|
8291
8423
|
return `${id} ${state} ${direction} ${outcome}`;
|
|
8292
8424
|
}
|
|
8293
8425
|
function colorState2(s) {
|
|
8294
8426
|
switch (s) {
|
|
8295
|
-
case
|
|
8296
|
-
return
|
|
8297
|
-
case
|
|
8298
|
-
return
|
|
8427
|
+
case import_sdk32.WorkLogStates.REQUESTED:
|
|
8428
|
+
return import_chalk36.default.yellow("requested");
|
|
8429
|
+
case import_sdk32.WorkLogStates.RESPONDED:
|
|
8430
|
+
return import_chalk36.default.green("responded");
|
|
8299
8431
|
}
|
|
8300
8432
|
}
|
|
8301
8433
|
function stateColumnWidth2() {
|
|
8302
8434
|
return 9;
|
|
8303
8435
|
}
|
|
8304
8436
|
function formatOutcome(w) {
|
|
8305
|
-
if (w.state ===
|
|
8306
|
-
if (w.responseError) return
|
|
8307
|
-
if (w.responseOutput) return
|
|
8308
|
-
return
|
|
8437
|
+
if (w.state === import_sdk32.WorkLogStates.REQUESTED) return import_chalk36.default.dim("(in flight)");
|
|
8438
|
+
if (w.responseError) return import_chalk36.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
|
|
8439
|
+
if (w.responseOutput) return import_chalk36.default.cyan("ok");
|
|
8440
|
+
return import_chalk36.default.dim("(empty response)");
|
|
8309
8441
|
}
|
|
8310
8442
|
function idHead3(id) {
|
|
8311
8443
|
if (id.length <= 12) return id;
|
|
@@ -8412,6 +8544,8 @@ async function main() {
|
|
|
8412
8544
|
registerAssetsCommand(program);
|
|
8413
8545
|
registerEscrowCommands(program);
|
|
8414
8546
|
registerWhoamiCommand(program);
|
|
8547
|
+
registerWhoisCommand(program);
|
|
8548
|
+
registerNameCommand(program);
|
|
8415
8549
|
registerLifecycleCommands(program);
|
|
8416
8550
|
registerSendHandshakeCommand(program);
|
|
8417
8551
|
registerSendHandshakeResponseCommand(program);
|