@garydevenay/emporion 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +213 -5
- package/dist/src/cli.js +1195 -182
- package/dist/src/cli.js.map +1 -1
- package/dist/src/context-store.d.ts +22 -0
- package/dist/src/context-store.js +133 -0
- package/dist/src/context-store.js.map +1 -0
- package/dist/src/daemon.d.ts +2 -0
- package/dist/src/daemon.js.map +1 -1
- package/dist/src/errors.d.ts +8 -0
- package/dist/src/errors.js +8 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/experience/deals-store.d.ts +37 -0
- package/dist/src/experience/deals-store.js +96 -0
- package/dist/src/experience/deals-store.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/wallet/config-store.d.ts +16 -0
- package/dist/src/wallet/config-store.js +180 -0
- package/dist/src/wallet/config-store.js.map +1 -0
- package/dist/src/wallet/index.d.ts +3 -0
- package/dist/src/wallet/index.js +4 -0
- package/dist/src/wallet/index.js.map +1 -0
- package/dist/src/wallet/ledger.d.ts +50 -0
- package/dist/src/wallet/ledger.js +340 -0
- package/dist/src/wallet/ledger.js.map +1 -0
- package/dist/src/wallet/nostr-nwc-adapter.d.ts +40 -0
- package/dist/src/wallet/nostr-nwc-adapter.js +506 -0
- package/dist/src/wallet/nostr-nwc-adapter.js.map +1 -0
- package/dist/src/wallet/nwc-adapter.d.ts +20 -0
- package/dist/src/wallet/nwc-adapter.js +233 -0
- package/dist/src/wallet/nwc-adapter.js.map +1 -0
- package/dist/src/wallet/service.d.ts +42 -0
- package/dist/src/wallet/service.js +390 -0
- package/dist/src/wallet/service.js.map +1 -0
- package/dist/src/wallet/types.d.ts +140 -0
- package/dist/src/wallet/types.js +2 -0
- package/dist/src/wallet/types.js.map +1 -0
- package/dist/test/experience.test.d.ts +1 -0
- package/dist/test/experience.test.js +232 -0
- package/dist/test/experience.test.js.map +1 -0
- package/dist/test/wallet.test.d.ts +1 -0
- package/dist/test/wallet.test.js +853 -0
- package/dist/test/wallet.test.js.map +1 -0
- package/package.json +2 -1
package/dist/src/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
4
5
|
import { once } from "node:events";
|
|
5
6
|
import { closeSync } from "node:fs";
|
|
6
7
|
import { readFile } from "node:fs/promises";
|
|
@@ -13,6 +14,11 @@ import { loadPersistentIdentityMaterial } from "./persistent-agent.js";
|
|
|
13
14
|
import * as Protocol from "./protocol/index.js";
|
|
14
15
|
import { sha256Hex } from "./protocol/shared.js";
|
|
15
16
|
import { TransportStorage } from "./storage.js";
|
|
17
|
+
import { WalletService } from "./wallet/index.js";
|
|
18
|
+
import { ContextStore } from "./context-store.js";
|
|
19
|
+
import { DealsStore } from "./experience/deals-store.js";
|
|
20
|
+
const DEFAULT_DAEMON_PROXY_TIMEOUT_MS = 5_000;
|
|
21
|
+
const WALLET_DAEMON_PROXY_TIMEOUT_MS = 30_000;
|
|
16
22
|
const DEFAULT_IO = {
|
|
17
23
|
stdout(message) {
|
|
18
24
|
process.stdout.write(message);
|
|
@@ -51,6 +57,12 @@ function parseArgs(argv) {
|
|
|
51
57
|
function commandMatches(commandPath, ...expected) {
|
|
52
58
|
return commandPath.length === expected.length && expected.every((value, index) => commandPath[index] === value);
|
|
53
59
|
}
|
|
60
|
+
function isContextCommand(commandPath) {
|
|
61
|
+
return commandPath[0] === "context";
|
|
62
|
+
}
|
|
63
|
+
function isWalletCommand(commandPath) {
|
|
64
|
+
return commandPath[0] === "wallet";
|
|
65
|
+
}
|
|
54
66
|
function getOptionValues(args, name) {
|
|
55
67
|
return args.options.get(name) ?? [];
|
|
56
68
|
}
|
|
@@ -92,6 +104,17 @@ function parseOptionalNonNegativeInteger(args, name) {
|
|
|
92
104
|
const value = getOptionalOption(args, name);
|
|
93
105
|
return value === undefined ? undefined : parseNonNegativeInteger(value, `--${name}`);
|
|
94
106
|
}
|
|
107
|
+
function parseOptionalIsoTimestamp(args, name) {
|
|
108
|
+
const value = getOptionalOption(args, name);
|
|
109
|
+
if (value === undefined) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
const epochMs = Date.parse(value);
|
|
113
|
+
if (Number.isNaN(epochMs)) {
|
|
114
|
+
throw new Error(`--${name} must be a valid ISO-8601 timestamp`);
|
|
115
|
+
}
|
|
116
|
+
return new Date(epochMs).toISOString();
|
|
117
|
+
}
|
|
95
118
|
function parseEnum(value, fieldName, allowed) {
|
|
96
119
|
if (allowed.includes(value)) {
|
|
97
120
|
return value;
|
|
@@ -193,16 +216,161 @@ function writeJson(io, value) {
|
|
|
193
216
|
function normalizeDataDirPath(dataDir) {
|
|
194
217
|
return path.resolve(dataDir);
|
|
195
218
|
}
|
|
219
|
+
function parsedArgsFromCommand(commandPath, options) {
|
|
220
|
+
const map = new Map();
|
|
221
|
+
for (const [name, value] of Object.entries(options)) {
|
|
222
|
+
if (value === undefined) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (typeof value === "boolean") {
|
|
226
|
+
if (value) {
|
|
227
|
+
map.set(name, ["true"]);
|
|
228
|
+
}
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (Array.isArray(value)) {
|
|
232
|
+
map.set(name, value.map((entry) => `${entry}`));
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
map.set(name, [`${value}`]);
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
commandPath: [...commandPath],
|
|
239
|
+
options: map
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
async function runNestedCommand(commandPath, options) {
|
|
243
|
+
return executeCapturedInDaemon(parsedArgsFromCommand(commandPath, options));
|
|
244
|
+
}
|
|
245
|
+
function ensureObjectIdPrefix(objectId, prefixes) {
|
|
246
|
+
const trimmed = objectId.trim();
|
|
247
|
+
if (!prefixes.some((prefix) => trimmed.startsWith(prefix))) {
|
|
248
|
+
throw new Error(`Unsupported object id: ${trimmed}`);
|
|
249
|
+
}
|
|
250
|
+
return trimmed;
|
|
251
|
+
}
|
|
252
|
+
function stageOrder(stage) {
|
|
253
|
+
switch (stage) {
|
|
254
|
+
case "draft":
|
|
255
|
+
return 0;
|
|
256
|
+
case "negotiating":
|
|
257
|
+
return 1;
|
|
258
|
+
case "agreed":
|
|
259
|
+
return 2;
|
|
260
|
+
case "in_progress":
|
|
261
|
+
return 3;
|
|
262
|
+
case "proof_submitted":
|
|
263
|
+
return 4;
|
|
264
|
+
case "proof_accepted":
|
|
265
|
+
return 5;
|
|
266
|
+
case "settlement_pending":
|
|
267
|
+
return 6;
|
|
268
|
+
case "settled":
|
|
269
|
+
return 7;
|
|
270
|
+
case "closed":
|
|
271
|
+
return 8;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function stageAtLeast(current, expected) {
|
|
275
|
+
return stageOrder(current) >= stageOrder(expected);
|
|
276
|
+
}
|
|
277
|
+
function toChangedObjects(record) {
|
|
278
|
+
const entries = [];
|
|
279
|
+
if (record.rootObjectKind && record.rootObjectId)
|
|
280
|
+
entries.push({ kind: record.rootObjectKind, id: record.rootObjectId });
|
|
281
|
+
if (record.proposalKind && record.proposalId)
|
|
282
|
+
entries.push({ kind: record.proposalKind, id: record.proposalId });
|
|
283
|
+
if (record.agreementId)
|
|
284
|
+
entries.push({ kind: "agreement", id: record.agreementId });
|
|
285
|
+
if (record.contractId)
|
|
286
|
+
entries.push({ kind: "contract", id: record.contractId });
|
|
287
|
+
if (record.evidenceId)
|
|
288
|
+
entries.push({ kind: "evidence-bundle", id: record.evidenceId });
|
|
289
|
+
if (record.invoiceId)
|
|
290
|
+
entries.push({ kind: "invoice", id: record.invoiceId });
|
|
291
|
+
if (record.paymentId)
|
|
292
|
+
entries.push({ kind: "payment", id: record.paymentId });
|
|
293
|
+
return entries;
|
|
294
|
+
}
|
|
295
|
+
function nextActionsForStage(stage) {
|
|
296
|
+
switch (stage) {
|
|
297
|
+
case "draft":
|
|
298
|
+
case "negotiating":
|
|
299
|
+
return ["deal.propose", "deal.accept"];
|
|
300
|
+
case "agreed":
|
|
301
|
+
return ["deal.start"];
|
|
302
|
+
case "in_progress":
|
|
303
|
+
return ["proof.submit"];
|
|
304
|
+
case "proof_submitted":
|
|
305
|
+
return ["proof.accept"];
|
|
306
|
+
case "proof_accepted":
|
|
307
|
+
return ["settlement.invoice.create", "settlement.pay"];
|
|
308
|
+
case "settlement_pending":
|
|
309
|
+
return ["settlement.pay", "settlement.status"];
|
|
310
|
+
case "settled":
|
|
311
|
+
return ["deal.status"];
|
|
312
|
+
case "closed":
|
|
313
|
+
return [];
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function writeDealResponse(io, command, deal, overrides) {
|
|
317
|
+
writeJson(io, {
|
|
318
|
+
command,
|
|
319
|
+
dealId: deal.dealId,
|
|
320
|
+
stage: deal.stage,
|
|
321
|
+
changedObjects: toChangedObjects(deal),
|
|
322
|
+
nextActions: nextActionsForStage(deal.stage),
|
|
323
|
+
safety: {
|
|
324
|
+
policy: "proof-gated",
|
|
325
|
+
earlySettlementAllowed: overrides?.safety?.earlySettlementAllowed ?? false
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
function asRecord(value, label) {
|
|
330
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
331
|
+
throw new Error(`Expected ${label} to be an object`);
|
|
332
|
+
}
|
|
333
|
+
return value;
|
|
334
|
+
}
|
|
335
|
+
function readString(value, fieldName) {
|
|
336
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
337
|
+
throw new Error(`Expected ${fieldName} to be a non-empty string`);
|
|
338
|
+
}
|
|
339
|
+
return value;
|
|
340
|
+
}
|
|
341
|
+
function inferIntentFromRootObjectKind(kind) {
|
|
342
|
+
return kind === "request" ? "sell" : "buy";
|
|
343
|
+
}
|
|
344
|
+
function inferRootObjectKindFromId(objectId) {
|
|
345
|
+
if (objectId.startsWith("emporion:request:")) {
|
|
346
|
+
return "request";
|
|
347
|
+
}
|
|
348
|
+
if (objectId.startsWith("emporion:listing:")) {
|
|
349
|
+
return "listing";
|
|
350
|
+
}
|
|
351
|
+
throw new Error(`Unsupported target object id for proposal: ${objectId}`);
|
|
352
|
+
}
|
|
353
|
+
function inferProposalKindFromId(proposalId) {
|
|
354
|
+
if (proposalId.startsWith("emporion:offer:")) {
|
|
355
|
+
return "offer";
|
|
356
|
+
}
|
|
357
|
+
if (proposalId.startsWith("emporion:bid:")) {
|
|
358
|
+
return "bid";
|
|
359
|
+
}
|
|
360
|
+
throw new Error(`Unsupported proposal id: ${proposalId}`);
|
|
361
|
+
}
|
|
196
362
|
async function openCliContext(dataDir) {
|
|
197
363
|
const identityMaterial = await loadPersistentIdentityMaterial(dataDir);
|
|
198
364
|
const repository = await Protocol.ProtocolRepository.create(dataDir);
|
|
199
365
|
const transportStorage = await TransportStorage.create(dataDir, identityMaterial.storagePrimaryKey, createLogger("error"));
|
|
366
|
+
const walletService = await WalletService.create({ dataDir });
|
|
200
367
|
await transportStorage.initializeDefaults();
|
|
201
368
|
return {
|
|
202
369
|
dataDir,
|
|
203
370
|
identityMaterial,
|
|
204
371
|
repository,
|
|
205
372
|
transportStorage,
|
|
373
|
+
walletService,
|
|
206
374
|
signer: {
|
|
207
375
|
did: identityMaterial.agentIdentity.did,
|
|
208
376
|
publicKey: identityMaterial.transportKeyPair.publicKey,
|
|
@@ -211,6 +379,7 @@ async function openCliContext(dataDir) {
|
|
|
211
379
|
};
|
|
212
380
|
}
|
|
213
381
|
async function closeCliContext(context) {
|
|
382
|
+
await context.walletService.close();
|
|
214
383
|
await context.transportStorage.close();
|
|
215
384
|
await context.repository.close();
|
|
216
385
|
}
|
|
@@ -224,7 +393,7 @@ async function withCliContext(dataDir, fn) {
|
|
|
224
393
|
}
|
|
225
394
|
const context = await openCliContext(dataDir);
|
|
226
395
|
try {
|
|
227
|
-
return await fn(context);
|
|
396
|
+
return await CLI_CONTEXT_STORAGE.run(context, async () => fn(context));
|
|
228
397
|
}
|
|
229
398
|
finally {
|
|
230
399
|
await closeCliContext(context);
|
|
@@ -1770,11 +1939,640 @@ async function handleMarketList(args, io) {
|
|
|
1770
1939
|
});
|
|
1771
1940
|
});
|
|
1772
1941
|
}
|
|
1942
|
+
async function handleContextAdd(args, io) {
|
|
1943
|
+
const name = requireOption(args, "name");
|
|
1944
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1945
|
+
const makeActive = hasFlag(args, "make-active");
|
|
1946
|
+
const store = new ContextStore();
|
|
1947
|
+
const snapshot = await store.add(name, dataDir, makeActive);
|
|
1948
|
+
writeJson(io, {
|
|
1949
|
+
command: "context.add",
|
|
1950
|
+
activeContext: snapshot.activeContext,
|
|
1951
|
+
contexts: snapshot.contexts
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1954
|
+
async function handleContextUse(args, io) {
|
|
1955
|
+
const name = requireOption(args, "name");
|
|
1956
|
+
const store = new ContextStore();
|
|
1957
|
+
const snapshot = await store.use(name);
|
|
1958
|
+
writeJson(io, {
|
|
1959
|
+
command: "context.use",
|
|
1960
|
+
activeContext: snapshot.activeContext,
|
|
1961
|
+
contexts: snapshot.contexts
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1964
|
+
async function handleContextList(io) {
|
|
1965
|
+
const store = new ContextStore();
|
|
1966
|
+
const snapshot = await store.snapshot();
|
|
1967
|
+
writeJson(io, {
|
|
1968
|
+
command: "context.list",
|
|
1969
|
+
activeContext: snapshot.activeContext,
|
|
1970
|
+
contexts: snapshot.contexts
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
async function handleContextShow(io) {
|
|
1974
|
+
const store = new ContextStore();
|
|
1975
|
+
const snapshot = await store.snapshot();
|
|
1976
|
+
const active = snapshot.activeContext
|
|
1977
|
+
? snapshot.contexts.find((entry) => entry.name === snapshot.activeContext)
|
|
1978
|
+
: undefined;
|
|
1979
|
+
writeJson(io, {
|
|
1980
|
+
command: "context.show",
|
|
1981
|
+
activeContext: snapshot.activeContext,
|
|
1982
|
+
active: active ?? null
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
async function handleContextRemove(args, io) {
|
|
1986
|
+
const name = requireOption(args, "name");
|
|
1987
|
+
const store = new ContextStore();
|
|
1988
|
+
const snapshot = await store.remove(name);
|
|
1989
|
+
writeJson(io, {
|
|
1990
|
+
command: "context.remove",
|
|
1991
|
+
activeContext: snapshot.activeContext,
|
|
1992
|
+
contexts: snapshot.contexts
|
|
1993
|
+
});
|
|
1994
|
+
}
|
|
1995
|
+
function applyWalletRuntimeKeyFromArgs(context, args) {
|
|
1996
|
+
const walletKey = getOptionalOption(args, "wallet-key");
|
|
1997
|
+
if (walletKey && walletKey.trim().length > 0) {
|
|
1998
|
+
context.walletService.setRuntimeKey(walletKey);
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
async function handleWalletConnectNwc(args, io) {
|
|
2002
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2003
|
+
const connectionUri = requireOption(args, "connection-uri");
|
|
2004
|
+
const publishEndpoint = hasFlag(args, "publish-payment-endpoint");
|
|
2005
|
+
await withCliContext(dataDir, async (context) => {
|
|
2006
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2007
|
+
const connected = await context.walletService.connect(connectionUri);
|
|
2008
|
+
let paymentEndpointEventId;
|
|
2009
|
+
if (publishEndpoint) {
|
|
2010
|
+
await ensureAgentProfileExists(context);
|
|
2011
|
+
const capabilities = getCsvOptionValues(args, "payment-capability");
|
|
2012
|
+
const accountId = getOptionalOption(args, "payment-account-id");
|
|
2013
|
+
const endpoint = {
|
|
2014
|
+
id: getOptionalOption(args, "payment-endpoint-id") ?? "wallet-nwc",
|
|
2015
|
+
network: "bitcoin",
|
|
2016
|
+
custodial: true,
|
|
2017
|
+
capabilities: capabilities.length > 0 ? capabilities : ["invoice.create", "invoice.pay", "auto-settle"],
|
|
2018
|
+
...(accountId ? { accountId } : {}),
|
|
2019
|
+
nodeUri: connected.endpoint
|
|
2020
|
+
};
|
|
2021
|
+
const result = await appendEnvelope(context, {
|
|
2022
|
+
objectKind: "agent-profile",
|
|
2023
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
2024
|
+
eventKind: "agent-profile.payment-endpoint-added",
|
|
2025
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
2026
|
+
payload: Protocol.paymentEndpointToJson(endpoint)
|
|
2027
|
+
});
|
|
2028
|
+
paymentEndpointEventId = result.envelope.eventId;
|
|
2029
|
+
}
|
|
2030
|
+
writeJson(io, {
|
|
2031
|
+
command: "wallet.connect.nwc",
|
|
2032
|
+
wallet: connected.status,
|
|
2033
|
+
endpoint: connected.endpoint,
|
|
2034
|
+
...(paymentEndpointEventId ? { paymentEndpointEventId } : {})
|
|
2035
|
+
});
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
async function handleWalletDisconnect(args, io) {
|
|
2039
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2040
|
+
await withCliContext(dataDir, async (context) => {
|
|
2041
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2042
|
+
const wallet = await context.walletService.disconnect();
|
|
2043
|
+
writeJson(io, {
|
|
2044
|
+
command: "wallet.disconnect",
|
|
2045
|
+
wallet
|
|
2046
|
+
});
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
2049
|
+
async function handleWalletStatus(args, io) {
|
|
2050
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2051
|
+
await withCliContext(dataDir, async (context) => {
|
|
2052
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2053
|
+
writeJson(io, {
|
|
2054
|
+
command: "wallet.status",
|
|
2055
|
+
wallet: await context.walletService.status()
|
|
2056
|
+
});
|
|
2057
|
+
});
|
|
2058
|
+
}
|
|
2059
|
+
async function handleWalletUnlock(args, io) {
|
|
2060
|
+
if (process.env.EMPORION_DAEMON !== "1") {
|
|
2061
|
+
throw new Error("wallet unlock requires a running daemon for this data-dir");
|
|
2062
|
+
}
|
|
2063
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2064
|
+
const walletKey = requireOption(args, "wallet-key");
|
|
2065
|
+
if (walletKey.trim().length === 0) {
|
|
2066
|
+
throw new Error("--wallet-key must not be blank");
|
|
2067
|
+
}
|
|
2068
|
+
await withCliContext(dataDir, async (context) => {
|
|
2069
|
+
context.walletService.setRuntimeKey(walletKey);
|
|
2070
|
+
writeJson(io, {
|
|
2071
|
+
command: "wallet.unlock",
|
|
2072
|
+
wallet: await context.walletService.status()
|
|
2073
|
+
});
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
async function handleWalletLock(args, io) {
|
|
2077
|
+
if (process.env.EMPORION_DAEMON !== "1") {
|
|
2078
|
+
throw new Error("wallet lock requires a running daemon for this data-dir");
|
|
2079
|
+
}
|
|
2080
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2081
|
+
await withCliContext(dataDir, async (context) => {
|
|
2082
|
+
context.walletService.setRuntimeKey(null);
|
|
2083
|
+
writeJson(io, {
|
|
2084
|
+
command: "wallet.lock",
|
|
2085
|
+
wallet: await context.walletService.status()
|
|
2086
|
+
});
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
async function handleWalletInvoiceCreate(args, io) {
|
|
2090
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2091
|
+
const amountSats = parsePositiveInteger(requireOption(args, "amount-sats"), "--amount-sats");
|
|
2092
|
+
const memo = getOptionalOption(args, "memo");
|
|
2093
|
+
const expiresAt = parseOptionalIsoTimestamp(args, "expires-at");
|
|
2094
|
+
await withCliContext(dataDir, async (context) => {
|
|
2095
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2096
|
+
const created = await context.walletService.createInvoice({
|
|
2097
|
+
amountSats,
|
|
2098
|
+
...(memo ? { memo } : {}),
|
|
2099
|
+
...(expiresAt ? { expiresAt } : {})
|
|
2100
|
+
});
|
|
2101
|
+
writeJson(io, {
|
|
2102
|
+
command: "wallet.invoice.create",
|
|
2103
|
+
invoice: created.invoice,
|
|
2104
|
+
bolt11: created.bolt11
|
|
2105
|
+
});
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
async function handleWalletPayBolt11(args, io) {
|
|
2109
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2110
|
+
const invoice = requireOption(args, "invoice");
|
|
2111
|
+
const sourceRef = getOptionalOption(args, "source-ref");
|
|
2112
|
+
await withCliContext(dataDir, async (context) => {
|
|
2113
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2114
|
+
const paid = await context.walletService.payInvoice({
|
|
2115
|
+
invoice,
|
|
2116
|
+
...(sourceRef ? { sourceRef } : {})
|
|
2117
|
+
});
|
|
2118
|
+
writeJson(io, {
|
|
2119
|
+
command: "wallet.pay.bolt11",
|
|
2120
|
+
payment: paid.payment
|
|
2121
|
+
});
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
async function handleWalletLedgerList(args, io) {
|
|
2125
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2126
|
+
const kindValue = getOptionalOption(args, "kind");
|
|
2127
|
+
const status = getOptionalOption(args, "status");
|
|
2128
|
+
const kind = kindValue ? parseEnum(kindValue, "--kind", ["invoice", "payment"]) : undefined;
|
|
2129
|
+
await withCliContext(dataDir, async (context) => {
|
|
2130
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2131
|
+
const filters = {
|
|
2132
|
+
...(kind ? { kind } : {}),
|
|
2133
|
+
...(status ? { status } : {})
|
|
2134
|
+
};
|
|
2135
|
+
writeJson(io, {
|
|
2136
|
+
command: "wallet.ledger.list",
|
|
2137
|
+
kind: kind ?? null,
|
|
2138
|
+
status: status ?? null,
|
|
2139
|
+
entries: await context.walletService.listLedger(filters)
|
|
2140
|
+
});
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
async function handleWalletKeyRotate(args, io) {
|
|
2144
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2145
|
+
const newKey = requireOption(args, "new-key");
|
|
2146
|
+
await withCliContext(dataDir, async (context) => {
|
|
2147
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2148
|
+
await context.walletService.rotateKey(newKey);
|
|
2149
|
+
writeJson(io, {
|
|
2150
|
+
command: "wallet.key.rotate",
|
|
2151
|
+
rotated: true
|
|
2152
|
+
});
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
async function handleDealOpen(args, io) {
|
|
2156
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2157
|
+
const intent = parseEnum(requireOption(args, "intent"), "--intent", ["buy", "sell"]);
|
|
2158
|
+
const marketplaceId = requireOption(args, "marketplace");
|
|
2159
|
+
const title = requireOption(args, "title");
|
|
2160
|
+
const amountSats = parsePositiveInteger(requireOption(args, "amount-sats"), "--amount-sats");
|
|
2161
|
+
const dealId = getOptionalOption(args, "deal-id") ?? `deal:${randomUUID()}`;
|
|
2162
|
+
await withCliContext(dataDir, async () => {
|
|
2163
|
+
const deals = await DealsStore.create(dataDir);
|
|
2164
|
+
if (deals.get(dealId)) {
|
|
2165
|
+
throw new Error(`Deal already exists: ${dealId}`);
|
|
2166
|
+
}
|
|
2167
|
+
const created = await runNestedCommand(["market", intent === "buy" ? "request" : "listing", "publish"], {
|
|
2168
|
+
"data-dir": dataDir,
|
|
2169
|
+
marketplace: marketplaceId,
|
|
2170
|
+
title,
|
|
2171
|
+
"amount-sats": `${amountSats}`
|
|
2172
|
+
});
|
|
2173
|
+
const createdRecord = asRecord(created, `${intent}.publish result`);
|
|
2174
|
+
const objectId = readString(createdRecord.objectId, "objectId");
|
|
2175
|
+
const nowIso = now();
|
|
2176
|
+
const deal = {
|
|
2177
|
+
dealId,
|
|
2178
|
+
stage: "negotiating",
|
|
2179
|
+
intent,
|
|
2180
|
+
marketplaceId,
|
|
2181
|
+
title,
|
|
2182
|
+
amountSats,
|
|
2183
|
+
rootObjectKind: intent === "buy" ? "request" : "listing",
|
|
2184
|
+
rootObjectId: objectId,
|
|
2185
|
+
createdAt: nowIso,
|
|
2186
|
+
updatedAt: nowIso
|
|
2187
|
+
};
|
|
2188
|
+
await deals.save(deal);
|
|
2189
|
+
writeDealResponse(io, "deal.open", deal);
|
|
2190
|
+
});
|
|
2191
|
+
}
|
|
2192
|
+
async function handleDealPropose(args, io) {
|
|
2193
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2194
|
+
const targetId = requireOption(args, "target-id");
|
|
2195
|
+
const amountSats = parsePositiveInteger(requireOption(args, "amount-sats"), "--amount-sats");
|
|
2196
|
+
const proposalId = getOptionalOption(args, "proposal-id");
|
|
2197
|
+
const proposerDid = getOptionalOption(args, "proposer-did");
|
|
2198
|
+
await withCliContext(dataDir, async (context) => {
|
|
2199
|
+
const rootObjectKind = inferRootObjectKindFromId(targetId);
|
|
2200
|
+
const deals = await DealsStore.create(dataDir);
|
|
2201
|
+
const targetState = rootObjectKind === "request"
|
|
2202
|
+
? await readRequiredState(context.repository, "request", targetId)
|
|
2203
|
+
: await readRequiredState(context.repository, "listing", targetId);
|
|
2204
|
+
const proposalKind = rootObjectKind === "request" ? "offer" : "bid";
|
|
2205
|
+
const proposed = await runNestedCommand(["market", proposalKind, "submit"], {
|
|
2206
|
+
"data-dir": dataDir,
|
|
2207
|
+
marketplace: targetState.marketplaceId,
|
|
2208
|
+
"target-object-id": targetId,
|
|
2209
|
+
"amount-sats": `${amountSats}`,
|
|
2210
|
+
...(proposerDid ? { "proposer-did": proposerDid } : {}),
|
|
2211
|
+
...(proposalId ? { id: proposalId } : {})
|
|
2212
|
+
});
|
|
2213
|
+
const proposedRecord = asRecord(proposed, `${proposalKind}.submit result`);
|
|
2214
|
+
const resolvedProposalId = readString(proposedRecord.objectId, "objectId");
|
|
2215
|
+
const existing = deals.findByRootObjectId(targetId);
|
|
2216
|
+
const nowIso = now();
|
|
2217
|
+
const deal = existing
|
|
2218
|
+
? await deals.update(existing.dealId, (current) => ({
|
|
2219
|
+
...current,
|
|
2220
|
+
stage: "negotiating",
|
|
2221
|
+
proposalKind,
|
|
2222
|
+
proposalId: resolvedProposalId,
|
|
2223
|
+
amountSats,
|
|
2224
|
+
updatedAt: nowIso
|
|
2225
|
+
}))
|
|
2226
|
+
: await deals.save({
|
|
2227
|
+
dealId: `deal:${randomUUID()}`,
|
|
2228
|
+
stage: "negotiating",
|
|
2229
|
+
intent: inferIntentFromRootObjectKind(rootObjectKind),
|
|
2230
|
+
marketplaceId: targetState.marketplaceId,
|
|
2231
|
+
title: "proposal-only-deal",
|
|
2232
|
+
amountSats,
|
|
2233
|
+
rootObjectKind,
|
|
2234
|
+
rootObjectId: targetId,
|
|
2235
|
+
proposalKind,
|
|
2236
|
+
proposalId: resolvedProposalId,
|
|
2237
|
+
createdAt: nowIso,
|
|
2238
|
+
updatedAt: nowIso
|
|
2239
|
+
});
|
|
2240
|
+
writeDealResponse(io, "deal.propose", deal);
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
2243
|
+
async function handleDealAccept(args, io) {
|
|
2244
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2245
|
+
const proposalId = requireOption(args, "proposal-id");
|
|
2246
|
+
const proposalKind = inferProposalKindFromId(proposalId);
|
|
2247
|
+
await withCliContext(dataDir, async () => {
|
|
2248
|
+
const deals = await DealsStore.create(dataDir);
|
|
2249
|
+
await runNestedCommand(["market", proposalKind, "accept"], {
|
|
2250
|
+
"data-dir": dataDir,
|
|
2251
|
+
id: proposalId
|
|
2252
|
+
});
|
|
2253
|
+
const existing = deals.findByProposalId(proposalId);
|
|
2254
|
+
const nowIso = now();
|
|
2255
|
+
const deal = existing
|
|
2256
|
+
? await deals.update(existing.dealId, (current) => ({
|
|
2257
|
+
...current,
|
|
2258
|
+
stage: "agreed",
|
|
2259
|
+
proposalKind,
|
|
2260
|
+
proposalId,
|
|
2261
|
+
updatedAt: nowIso
|
|
2262
|
+
}))
|
|
2263
|
+
: await deals.save({
|
|
2264
|
+
dealId: `deal:${randomUUID()}`,
|
|
2265
|
+
stage: "agreed",
|
|
2266
|
+
proposalKind,
|
|
2267
|
+
proposalId,
|
|
2268
|
+
createdAt: nowIso,
|
|
2269
|
+
updatedAt: nowIso
|
|
2270
|
+
});
|
|
2271
|
+
writeDealResponse(io, "deal.accept", deal);
|
|
2272
|
+
});
|
|
2273
|
+
}
|
|
2274
|
+
async function handleDealStart(args, io) {
|
|
2275
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2276
|
+
const proposalId = requireOption(args, "proposal-id");
|
|
2277
|
+
const scope = requireOption(args, "scope");
|
|
2278
|
+
const milestoneId = requireOption(args, "milestone-id");
|
|
2279
|
+
const milestoneTitle = requireOption(args, "milestone-title");
|
|
2280
|
+
const deadline = parseOptionalIsoTimestamp(args, "deadline");
|
|
2281
|
+
if (!deadline) {
|
|
2282
|
+
throw new Error("--deadline is required");
|
|
2283
|
+
}
|
|
2284
|
+
const deliverableKind = parseEnum(requireOption(args, "deliverable-kind"), "--deliverable-kind", ["artifact", "generic", "oracle-claim"]);
|
|
2285
|
+
const requiredArtifactKinds = getCsvOptionValues(args, "required-artifact-kind");
|
|
2286
|
+
if (requiredArtifactKinds.length === 0) {
|
|
2287
|
+
throw new Error("--required-artifact-kind must include at least one value");
|
|
2288
|
+
}
|
|
2289
|
+
const proposalKind = inferProposalKindFromId(proposalId);
|
|
2290
|
+
await withCliContext(dataDir, async (context) => {
|
|
2291
|
+
const deals = await DealsStore.create(dataDir);
|
|
2292
|
+
const proposalState = proposalKind === "offer"
|
|
2293
|
+
? await readRequiredState(context.repository, "offer", proposalId)
|
|
2294
|
+
: await readRequiredState(context.repository, "bid", proposalId);
|
|
2295
|
+
if (proposalState.status !== "accepted") {
|
|
2296
|
+
throw new Error(`Proposal must be accepted before deal start: ${proposalId}`);
|
|
2297
|
+
}
|
|
2298
|
+
const agreement = await runNestedCommand(["market", "agreement", "create"], {
|
|
2299
|
+
"data-dir": dataDir,
|
|
2300
|
+
"source-kind": proposalKind,
|
|
2301
|
+
"source-id": proposalId,
|
|
2302
|
+
deliverable: [milestoneTitle],
|
|
2303
|
+
counterparty: [context.identityMaterial.agentIdentity.did, proposalState.proposerDid],
|
|
2304
|
+
"amount-sats": `${proposalState.paymentTerms.amountSats}`
|
|
2305
|
+
});
|
|
2306
|
+
const agreementRecord = asRecord(agreement, "agreement.create result");
|
|
2307
|
+
const agreementId = readString(agreementRecord.objectId, "objectId");
|
|
2308
|
+
const milestonesJson = JSON.stringify([{
|
|
2309
|
+
milestoneId,
|
|
2310
|
+
title: milestoneTitle,
|
|
2311
|
+
deliverableSchema: {
|
|
2312
|
+
kind: deliverableKind,
|
|
2313
|
+
requiredArtifactKinds
|
|
2314
|
+
},
|
|
2315
|
+
proofPolicy: {
|
|
2316
|
+
allowedModes: ["artifact-verifiable"],
|
|
2317
|
+
verifierRefs: [],
|
|
2318
|
+
minArtifacts: 1,
|
|
2319
|
+
requireCounterpartyAcceptance: true
|
|
2320
|
+
},
|
|
2321
|
+
settlementAdapters: []
|
|
2322
|
+
}]);
|
|
2323
|
+
const contract = await runNestedCommand(["contract", "create"], {
|
|
2324
|
+
"data-dir": dataDir,
|
|
2325
|
+
"origin-kind": "agreement",
|
|
2326
|
+
"origin-id": agreementId,
|
|
2327
|
+
party: [context.identityMaterial.agentIdentity.did, proposalState.proposerDid],
|
|
2328
|
+
scope,
|
|
2329
|
+
"milestones-json": milestonesJson,
|
|
2330
|
+
"deliverable-schema-json": JSON.stringify({ kind: deliverableKind, requiredArtifactKinds }),
|
|
2331
|
+
"proof-policy-json": JSON.stringify({
|
|
2332
|
+
allowedModes: ["artifact-verifiable"],
|
|
2333
|
+
verifierRefs: [],
|
|
2334
|
+
minArtifacts: 1,
|
|
2335
|
+
requireCounterpartyAcceptance: true
|
|
2336
|
+
}),
|
|
2337
|
+
"resolution-policy-json": JSON.stringify({ mode: "mutual", deterministicVerifierIds: [] }),
|
|
2338
|
+
"settlement-policy-json": JSON.stringify({ adapters: [], releaseCondition: "contract-completed" }),
|
|
2339
|
+
"deadline-policy-json": JSON.stringify({ milestoneDeadlines: { [milestoneId]: deadline } })
|
|
2340
|
+
});
|
|
2341
|
+
const contractRecord = asRecord(contract, "contract.create result");
|
|
2342
|
+
const contractId = readString(contractRecord.objectId, "objectId");
|
|
2343
|
+
await runNestedCommand(["contract", "open-milestone"], {
|
|
2344
|
+
"data-dir": dataDir,
|
|
2345
|
+
id: contractId,
|
|
2346
|
+
"milestone-id": milestoneId
|
|
2347
|
+
});
|
|
2348
|
+
const existing = deals.findByProposalId(proposalId);
|
|
2349
|
+
const nowIso = now();
|
|
2350
|
+
const deal = existing
|
|
2351
|
+
? await deals.update(existing.dealId, (current) => ({
|
|
2352
|
+
...current,
|
|
2353
|
+
stage: "in_progress",
|
|
2354
|
+
proposalKind,
|
|
2355
|
+
proposalId,
|
|
2356
|
+
agreementId,
|
|
2357
|
+
contractId,
|
|
2358
|
+
milestoneId,
|
|
2359
|
+
updatedAt: nowIso
|
|
2360
|
+
}))
|
|
2361
|
+
: await deals.save({
|
|
2362
|
+
dealId: `deal:${randomUUID()}`,
|
|
2363
|
+
stage: "in_progress",
|
|
2364
|
+
proposalKind,
|
|
2365
|
+
proposalId,
|
|
2366
|
+
agreementId,
|
|
2367
|
+
contractId,
|
|
2368
|
+
milestoneId,
|
|
2369
|
+
createdAt: nowIso,
|
|
2370
|
+
updatedAt: nowIso
|
|
2371
|
+
});
|
|
2372
|
+
writeDealResponse(io, "deal.start", deal);
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2375
|
+
async function handleDealStatus(args, io) {
|
|
2376
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2377
|
+
const dealId = requireOption(args, "deal-id");
|
|
2378
|
+
const deals = await DealsStore.create(dataDir);
|
|
2379
|
+
const deal = deals.get(dealId);
|
|
2380
|
+
if (!deal) {
|
|
2381
|
+
throw new Error(`Unknown deal: ${dealId}`);
|
|
2382
|
+
}
|
|
2383
|
+
writeDealResponse(io, "deal.status", deal);
|
|
2384
|
+
}
|
|
2385
|
+
async function handleProofSubmit(args, io) {
|
|
2386
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2387
|
+
const dealId = requireOption(args, "deal-id");
|
|
2388
|
+
const milestoneId = requireOption(args, "milestone-id");
|
|
2389
|
+
const preset = parseEnum(requireOption(args, "proof-preset"), "--proof-preset", ["simple-artifact"]);
|
|
2390
|
+
if (preset !== "simple-artifact") {
|
|
2391
|
+
throw new Error(`Unsupported --proof-preset: ${preset}`);
|
|
2392
|
+
}
|
|
2393
|
+
const artifactId = requireOption(args, "artifact-id");
|
|
2394
|
+
const artifactHash = requireOption(args, "artifact-hash");
|
|
2395
|
+
const repro = getOptionalOption(args, "repro");
|
|
2396
|
+
await withCliContext(dataDir, async () => {
|
|
2397
|
+
const deals = await DealsStore.create(dataDir);
|
|
2398
|
+
const existing = deals.get(dealId);
|
|
2399
|
+
if (!existing) {
|
|
2400
|
+
throw new Error(`Unknown deal: ${dealId}`);
|
|
2401
|
+
}
|
|
2402
|
+
if (!existing.contractId) {
|
|
2403
|
+
throw new Error("Deal has no contract yet; run deal start first");
|
|
2404
|
+
}
|
|
2405
|
+
if (!stageAtLeast(existing.stage, "in_progress")) {
|
|
2406
|
+
throw new Error("Deal is not ready for proof submission");
|
|
2407
|
+
}
|
|
2408
|
+
const evidence = await runNestedCommand(["evidence", "record"], {
|
|
2409
|
+
"data-dir": dataDir,
|
|
2410
|
+
"contract-id": existing.contractId,
|
|
2411
|
+
"milestone-id": milestoneId,
|
|
2412
|
+
"proof-mode": "artifact-verifiable",
|
|
2413
|
+
"artifact-json": JSON.stringify([{ artifactId, hash: artifactHash }]),
|
|
2414
|
+
"verifier-json": JSON.stringify([{ verifierId: "simple-artifact-check", verifierKind: "human-review" }]),
|
|
2415
|
+
...(repro ? { repro } : {})
|
|
2416
|
+
});
|
|
2417
|
+
const evidenceRecord = asRecord(evidence, "evidence.record result");
|
|
2418
|
+
const evidenceId = readString(evidenceRecord.objectId, "objectId");
|
|
2419
|
+
await runNestedCommand(["contract", "submit-milestone"], {
|
|
2420
|
+
"data-dir": dataDir,
|
|
2421
|
+
id: existing.contractId,
|
|
2422
|
+
"milestone-id": milestoneId,
|
|
2423
|
+
"evidence-bundle-id": evidenceId
|
|
2424
|
+
});
|
|
2425
|
+
const nowIso = now();
|
|
2426
|
+
const deal = await deals.update(dealId, (current) => ({
|
|
2427
|
+
...current,
|
|
2428
|
+
stage: "proof_submitted",
|
|
2429
|
+
milestoneId,
|
|
2430
|
+
evidenceId,
|
|
2431
|
+
updatedAt: nowIso
|
|
2432
|
+
}));
|
|
2433
|
+
writeDealResponse(io, "proof.submit", deal);
|
|
2434
|
+
});
|
|
2435
|
+
}
|
|
2436
|
+
async function handleProofAccept(args, io) {
|
|
2437
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2438
|
+
const dealId = requireOption(args, "deal-id");
|
|
2439
|
+
const milestoneId = requireOption(args, "milestone-id");
|
|
2440
|
+
await withCliContext(dataDir, async () => {
|
|
2441
|
+
const deals = await DealsStore.create(dataDir);
|
|
2442
|
+
const existing = deals.get(dealId);
|
|
2443
|
+
if (!existing) {
|
|
2444
|
+
throw new Error(`Unknown deal: ${dealId}`);
|
|
2445
|
+
}
|
|
2446
|
+
if (!existing.contractId) {
|
|
2447
|
+
throw new Error("Deal has no contract yet");
|
|
2448
|
+
}
|
|
2449
|
+
if (!stageAtLeast(existing.stage, "proof_submitted")) {
|
|
2450
|
+
throw new Error("Deal proof must be submitted before acceptance");
|
|
2451
|
+
}
|
|
2452
|
+
await runNestedCommand(["contract", "accept-milestone"], {
|
|
2453
|
+
"data-dir": dataDir,
|
|
2454
|
+
id: existing.contractId,
|
|
2455
|
+
"milestone-id": milestoneId
|
|
2456
|
+
});
|
|
2457
|
+
const nowIso = now();
|
|
2458
|
+
const deal = await deals.update(dealId, (current) => ({
|
|
2459
|
+
...current,
|
|
2460
|
+
stage: "proof_accepted",
|
|
2461
|
+
milestoneId,
|
|
2462
|
+
updatedAt: nowIso
|
|
2463
|
+
}));
|
|
2464
|
+
writeDealResponse(io, "proof.accept", deal);
|
|
2465
|
+
});
|
|
2466
|
+
}
|
|
2467
|
+
async function handleSettlementInvoiceCreate(args, io) {
|
|
2468
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2469
|
+
const dealId = requireOption(args, "deal-id");
|
|
2470
|
+
const amountSats = parsePositiveInteger(requireOption(args, "amount-sats"), "--amount-sats");
|
|
2471
|
+
const memo = getOptionalOption(args, "memo");
|
|
2472
|
+
const expiresAt = parseOptionalIsoTimestamp(args, "expires-at");
|
|
2473
|
+
const allowEarlySettlement = hasFlag(args, "allow-early-settlement");
|
|
2474
|
+
await withCliContext(dataDir, async (context) => {
|
|
2475
|
+
const deals = await DealsStore.create(dataDir);
|
|
2476
|
+
const existing = deals.get(dealId);
|
|
2477
|
+
if (!existing) {
|
|
2478
|
+
throw new Error(`Unknown deal: ${dealId}`);
|
|
2479
|
+
}
|
|
2480
|
+
if (!allowEarlySettlement && !stageAtLeast(existing.stage, "proof_accepted")) {
|
|
2481
|
+
throw new Error("Settlement invoice creation is proof-gated. Use --allow-early-settlement to override.");
|
|
2482
|
+
}
|
|
2483
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2484
|
+
const created = await context.walletService.createInvoice({
|
|
2485
|
+
amountSats,
|
|
2486
|
+
...(memo ? { memo } : {}),
|
|
2487
|
+
...(expiresAt ? { expiresAt } : {})
|
|
2488
|
+
});
|
|
2489
|
+
const nowIso = now();
|
|
2490
|
+
const deal = await deals.update(dealId, (current) => ({
|
|
2491
|
+
...current,
|
|
2492
|
+
stage: "settlement_pending",
|
|
2493
|
+
invoiceId: created.invoice.id,
|
|
2494
|
+
invoiceBolt11: created.bolt11,
|
|
2495
|
+
updatedAt: nowIso
|
|
2496
|
+
}));
|
|
2497
|
+
writeDealResponse(io, "settlement.invoice.create", deal, {
|
|
2498
|
+
safety: { earlySettlementAllowed: allowEarlySettlement }
|
|
2499
|
+
});
|
|
2500
|
+
});
|
|
2501
|
+
}
|
|
2502
|
+
async function handleSettlementPay(args, io) {
|
|
2503
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2504
|
+
const dealId = requireOption(args, "deal-id");
|
|
2505
|
+
const invoice = requireOption(args, "invoice");
|
|
2506
|
+
const allowEarlySettlement = hasFlag(args, "allow-early-settlement");
|
|
2507
|
+
await withCliContext(dataDir, async (context) => {
|
|
2508
|
+
const deals = await DealsStore.create(dataDir);
|
|
2509
|
+
const existing = deals.get(dealId);
|
|
2510
|
+
if (!existing) {
|
|
2511
|
+
throw new Error(`Unknown deal: ${dealId}`);
|
|
2512
|
+
}
|
|
2513
|
+
if (!allowEarlySettlement && !stageAtLeast(existing.stage, "proof_accepted")) {
|
|
2514
|
+
throw new Error("Settlement payment is proof-gated. Use --allow-early-settlement to override.");
|
|
2515
|
+
}
|
|
2516
|
+
applyWalletRuntimeKeyFromArgs(context, args);
|
|
2517
|
+
const sourceRef = existing.contractId
|
|
2518
|
+
? `${existing.contractId}:${existing.milestoneId ?? "milestone"}`
|
|
2519
|
+
: dealId;
|
|
2520
|
+
const paid = await context.walletService.payInvoice({
|
|
2521
|
+
invoice,
|
|
2522
|
+
sourceRef
|
|
2523
|
+
});
|
|
2524
|
+
const nowIso = now();
|
|
2525
|
+
const deal = await deals.update(dealId, (current) => ({
|
|
2526
|
+
...current,
|
|
2527
|
+
stage: "settled",
|
|
2528
|
+
paymentId: paid.payment.id,
|
|
2529
|
+
updatedAt: nowIso
|
|
2530
|
+
}));
|
|
2531
|
+
writeDealResponse(io, "settlement.pay", deal, {
|
|
2532
|
+
safety: { earlySettlementAllowed: allowEarlySettlement }
|
|
2533
|
+
});
|
|
2534
|
+
});
|
|
2535
|
+
}
|
|
2536
|
+
async function handleSettlementStatus(args, io) {
|
|
2537
|
+
const dataDir = requireOption(args, "data-dir");
|
|
2538
|
+
const dealId = requireOption(args, "deal-id");
|
|
2539
|
+
const deals = await DealsStore.create(dataDir);
|
|
2540
|
+
const deal = deals.get(dealId);
|
|
2541
|
+
if (!deal) {
|
|
2542
|
+
throw new Error(`Unknown deal: ${dealId}`);
|
|
2543
|
+
}
|
|
2544
|
+
writeDealResponse(io, "settlement.status", deal);
|
|
2545
|
+
}
|
|
1773
2546
|
function usage() {
|
|
1774
2547
|
return [
|
|
1775
2548
|
"Usage:",
|
|
2549
|
+
" Global data-dir resolution: --data-dir <path> > --context <name> > active context",
|
|
2550
|
+
" emporion context add --name <context> --data-dir <path> [--make-active]",
|
|
2551
|
+
" emporion context use --name <context>",
|
|
2552
|
+
" emporion context list",
|
|
2553
|
+
" emporion context show",
|
|
2554
|
+
" emporion context remove --name <context>",
|
|
1776
2555
|
" emporion agent init --data-dir <path> [--display-name <name>] [--bio <text>]",
|
|
1777
2556
|
" emporion agent show --data-dir <path>",
|
|
2557
|
+
" emporion wallet connect nwc --data-dir <path> --connection-uri <uri> [--publish-payment-endpoint]",
|
|
2558
|
+
" emporion wallet disconnect --data-dir <path>",
|
|
2559
|
+
" emporion wallet status --data-dir <path>",
|
|
2560
|
+
" emporion wallet unlock [--data-dir <path>|--context <name>] --wallet-key <key-material>",
|
|
2561
|
+
" emporion wallet lock [--data-dir <path>|--context <name>]",
|
|
2562
|
+
" emporion wallet invoice create --data-dir <path> --amount-sats <n> [--memo <text>] [--expires-at <iso>]",
|
|
2563
|
+
" emporion wallet pay bolt11 --data-dir <path> --invoice <bolt11>",
|
|
2564
|
+
" emporion wallet ledger list --data-dir <path> [--kind <invoice|payment>] [--status <status>]",
|
|
2565
|
+
" emporion wallet key rotate --data-dir <path> --new-key <key-material>",
|
|
2566
|
+
" emporion deal open [--data-dir <path>|--context <name>] --intent <buy|sell> --marketplace <id> --title <text> --amount-sats <n> [--deal-id <id>]",
|
|
2567
|
+
" emporion deal propose [--data-dir <path>|--context <name>] --target-id <object-id> --amount-sats <n> [--proposal-id <id>] [--proposer-did <did>]",
|
|
2568
|
+
" emporion deal accept [--data-dir <path>|--context <name>] --proposal-id <offer-or-bid-id>",
|
|
2569
|
+
" emporion deal start [--data-dir <path>|--context <name>] --proposal-id <offer-or-bid-id> --scope <text> --milestone-id <id> --milestone-title <text> --deadline <iso> --deliverable-kind <artifact|generic|oracle-claim> --required-artifact-kind <kind>[,<kind>...]",
|
|
2570
|
+
" emporion deal status [--data-dir <path>|--context <name>] --deal-id <id>",
|
|
2571
|
+
" emporion proof submit [--data-dir <path>|--context <name>] --deal-id <id> --milestone-id <id> --proof-preset <simple-artifact> --artifact-id <id> --artifact-hash <hex> [--repro <text>]",
|
|
2572
|
+
" emporion proof accept [--data-dir <path>|--context <name>] --deal-id <id> --milestone-id <id>",
|
|
2573
|
+
" emporion settlement invoice create [--data-dir <path>|--context <name>] --deal-id <id> --amount-sats <n> [--memo <text>] [--expires-at <iso>]",
|
|
2574
|
+
" emporion settlement pay [--data-dir <path>|--context <name>] --deal-id <id> --invoice <bolt11>",
|
|
2575
|
+
" emporion settlement status [--data-dir <path>|--context <name>] --deal-id <id>",
|
|
1778
2576
|
" emporion agent payment-endpoint add --data-dir <path> --id <id> --capability <cap>[,<cap>...]",
|
|
1779
2577
|
" emporion agent wallet-attestation add --data-dir <path> --attestation-id <id> --wallet-account-id <id> --balance-sats <n> --expires-at <iso>",
|
|
1780
2578
|
" emporion agent feedback add --data-dir <path> --credential-id <id> --issuer-did <did> --contract-id <id> --agreement-id <id> --score <n> --max-score <n>",
|
|
@@ -1805,6 +2603,53 @@ function usage() {
|
|
|
1805
2603
|
function getDataDirFromArgs(args) {
|
|
1806
2604
|
return getOptionalOption(args, "data-dir");
|
|
1807
2605
|
}
|
|
2606
|
+
async function withResolvedDataDir(args) {
|
|
2607
|
+
if (isContextCommand(args.commandPath)) {
|
|
2608
|
+
return args;
|
|
2609
|
+
}
|
|
2610
|
+
if (getOptionalOption(args, "data-dir")) {
|
|
2611
|
+
return args;
|
|
2612
|
+
}
|
|
2613
|
+
const requestedContext = getOptionalOption(args, "context");
|
|
2614
|
+
const store = new ContextStore();
|
|
2615
|
+
const resolved = await store.resolveDataDir(requestedContext);
|
|
2616
|
+
if (requestedContext && !resolved) {
|
|
2617
|
+
throw new Error(`Unknown context: ${requestedContext}`);
|
|
2618
|
+
}
|
|
2619
|
+
if (!resolved) {
|
|
2620
|
+
return args;
|
|
2621
|
+
}
|
|
2622
|
+
const options = new Map(args.options);
|
|
2623
|
+
options.set("data-dir", [resolved]);
|
|
2624
|
+
return {
|
|
2625
|
+
commandPath: [...args.commandPath],
|
|
2626
|
+
options
|
|
2627
|
+
};
|
|
2628
|
+
}
|
|
2629
|
+
function withDaemonWalletKeyForwarding(args) {
|
|
2630
|
+
if (!isWalletCommand(args.commandPath)) {
|
|
2631
|
+
return args;
|
|
2632
|
+
}
|
|
2633
|
+
if (getOptionalOption(args, "wallet-key")) {
|
|
2634
|
+
return args;
|
|
2635
|
+
}
|
|
2636
|
+
const walletKey = process.env.EMPORION_WALLET_KEY;
|
|
2637
|
+
if (!walletKey || walletKey.trim().length === 0) {
|
|
2638
|
+
return args;
|
|
2639
|
+
}
|
|
2640
|
+
const options = new Map(args.options);
|
|
2641
|
+
options.set("wallet-key", [walletKey]);
|
|
2642
|
+
return {
|
|
2643
|
+
commandPath: [...args.commandPath],
|
|
2644
|
+
options
|
|
2645
|
+
};
|
|
2646
|
+
}
|
|
2647
|
+
function getDaemonProxyTimeoutMs(commandPath) {
|
|
2648
|
+
if (isWalletCommand(commandPath) || commandPath[0] === "settlement") {
|
|
2649
|
+
return WALLET_DAEMON_PROXY_TIMEOUT_MS;
|
|
2650
|
+
}
|
|
2651
|
+
return DEFAULT_DAEMON_PROXY_TIMEOUT_MS;
|
|
2652
|
+
}
|
|
1808
2653
|
function createCaptureIo() {
|
|
1809
2654
|
const stdout = [];
|
|
1810
2655
|
const stderr = [];
|
|
@@ -1944,7 +2789,7 @@ async function proxyParsedArgsToDaemon(args, io) {
|
|
|
1944
2789
|
if (!dataDir) {
|
|
1945
2790
|
return 1;
|
|
1946
2791
|
}
|
|
1947
|
-
const response = await sendDaemonCommand(dataDir, daemonRequestFromParsed(args.commandPath, daemonRequestOptionsToRecord(args.options)));
|
|
2792
|
+
const response = await sendDaemonCommand(dataDir, daemonRequestFromParsed(args.commandPath, daemonRequestOptionsToRecord(args.options)), getDaemonProxyTimeoutMs(args.commandPath));
|
|
1948
2793
|
if (!response.ok) {
|
|
1949
2794
|
throw new Error(response.error ?? "Daemon command failed");
|
|
1950
2795
|
}
|
|
@@ -2088,7 +2933,7 @@ async function handleDaemonLogs(args, io) {
|
|
|
2088
2933
|
process.off("SIGTERM", stop);
|
|
2089
2934
|
}
|
|
2090
2935
|
}
|
|
2091
|
-
async function buildDaemonSharedContext(dataDir, transport) {
|
|
2936
|
+
async function buildDaemonSharedContext(dataDir, transport, walletService) {
|
|
2092
2937
|
const identityMaterial = transport.getIdentityMaterial();
|
|
2093
2938
|
const repository = await Protocol.ProtocolRepository.create(dataDir);
|
|
2094
2939
|
return {
|
|
@@ -2096,6 +2941,7 @@ async function buildDaemonSharedContext(dataDir, transport) {
|
|
|
2096
2941
|
identityMaterial,
|
|
2097
2942
|
repository,
|
|
2098
2943
|
transportStorage: transport.getStorage(),
|
|
2944
|
+
walletService,
|
|
2099
2945
|
signer: {
|
|
2100
2946
|
did: identityMaterial.agentIdentity.did,
|
|
2101
2947
|
publicKey: identityMaterial.transportKeyPair.publicKey,
|
|
@@ -2103,7 +2949,7 @@ async function buildDaemonSharedContext(dataDir, transport) {
|
|
|
2103
2949
|
}
|
|
2104
2950
|
};
|
|
2105
2951
|
}
|
|
2106
|
-
function buildDaemonStatus(dataDir, startedAt, transport) {
|
|
2952
|
+
function buildDaemonStatus(dataDir, startedAt, transport, walletStatus) {
|
|
2107
2953
|
return {
|
|
2108
2954
|
dataDir: normalizeDataDirPath(dataDir),
|
|
2109
2955
|
pid: process.pid,
|
|
@@ -2113,9 +2959,56 @@ function buildDaemonStatus(dataDir, startedAt, transport) {
|
|
|
2113
2959
|
logPath: getDaemonLogPath(dataDir),
|
|
2114
2960
|
topics: transport.getJoinedTopics(),
|
|
2115
2961
|
connectedPeers: [...transport.getPeerSessions().values()],
|
|
2962
|
+
wallet: walletStatus,
|
|
2116
2963
|
healthy: true
|
|
2117
2964
|
};
|
|
2118
2965
|
}
|
|
2966
|
+
function collectAutoSettleCandidates(snapshot) {
|
|
2967
|
+
const candidates = [];
|
|
2968
|
+
for (const offer of snapshot.offers.values()) {
|
|
2969
|
+
if (offer.status !== "accepted") {
|
|
2970
|
+
continue;
|
|
2971
|
+
}
|
|
2972
|
+
for (const lightningRef of offer.lightningRefs) {
|
|
2973
|
+
candidates.push({
|
|
2974
|
+
triggerObjectKind: "offer",
|
|
2975
|
+
triggerObjectId: offer.objectId,
|
|
2976
|
+
eventId: offer.latestEventId,
|
|
2977
|
+
lightningRef,
|
|
2978
|
+
amountSats: offer.paymentTerms.amountSats
|
|
2979
|
+
});
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
for (const bid of snapshot.bids.values()) {
|
|
2983
|
+
if (bid.status !== "accepted") {
|
|
2984
|
+
continue;
|
|
2985
|
+
}
|
|
2986
|
+
for (const lightningRef of bid.lightningRefs) {
|
|
2987
|
+
candidates.push({
|
|
2988
|
+
triggerObjectKind: "bid",
|
|
2989
|
+
triggerObjectId: bid.objectId,
|
|
2990
|
+
eventId: bid.latestEventId,
|
|
2991
|
+
lightningRef,
|
|
2992
|
+
amountSats: bid.paymentTerms.amountSats
|
|
2993
|
+
});
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
for (const agreement of snapshot.agreements.values()) {
|
|
2997
|
+
if (agreement.status !== "active") {
|
|
2998
|
+
continue;
|
|
2999
|
+
}
|
|
3000
|
+
for (const lightningRef of agreement.lightningRefs) {
|
|
3001
|
+
candidates.push({
|
|
3002
|
+
triggerObjectKind: "agreement",
|
|
3003
|
+
triggerObjectId: agreement.objectId,
|
|
3004
|
+
eventId: agreement.latestEventId,
|
|
3005
|
+
lightningRef,
|
|
3006
|
+
amountSats: agreement.paymentTerms.amountSats
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
}
|
|
3010
|
+
return candidates;
|
|
3011
|
+
}
|
|
2119
3012
|
async function runProtocolDiscoveryWatcher(transport, seenControlLengths, io) {
|
|
2120
3013
|
for (const session of transport.getPeerSessions().values()) {
|
|
2121
3014
|
const remoteFeed = transport.getRemoteFeed(session.remoteControlFeedKey);
|
|
@@ -2144,56 +3037,118 @@ async function waitForProcessSignal() {
|
|
|
2144
3037
|
}
|
|
2145
3038
|
async function handleDaemonRun(args, io) {
|
|
2146
3039
|
const dataDir = requireOption(args, "data-dir");
|
|
2147
|
-
const transport = await AgentTransport.create(buildTransportConfigFromArgs(args));
|
|
2148
3040
|
const startup = getDaemonStartupOptions(args);
|
|
3041
|
+
const walletService = await WalletService.create({
|
|
3042
|
+
dataDir,
|
|
3043
|
+
logger: createLogger("warn")
|
|
3044
|
+
});
|
|
3045
|
+
walletService.setRuntimeKey(process.env.EMPORION_WALLET_KEY ?? null);
|
|
3046
|
+
let transport;
|
|
2149
3047
|
let sharedContext;
|
|
2150
3048
|
let daemon;
|
|
2151
3049
|
let discoveryInterval;
|
|
3050
|
+
let walletPollInterval;
|
|
3051
|
+
let autoSettleInterval;
|
|
3052
|
+
let walletStatus = await walletService.daemonStatus();
|
|
3053
|
+
let walletPollRunning = false;
|
|
3054
|
+
let autoSettleRunning = false;
|
|
2152
3055
|
const seenControlLengths = new Map();
|
|
2153
3056
|
const startedAt = new Date().toISOString();
|
|
2154
3057
|
try {
|
|
3058
|
+
transport = await AgentTransport.create(buildTransportConfigFromArgs(args));
|
|
2155
3059
|
await transport.start();
|
|
2156
|
-
|
|
2157
|
-
|
|
3060
|
+
const activeTransport = transport;
|
|
3061
|
+
sharedContext = await buildDaemonSharedContext(dataDir, activeTransport, walletService);
|
|
3062
|
+
const topics = buildTopicsFromArgs(args, activeTransport.identity.did);
|
|
2158
3063
|
startup.topics.push(...topics);
|
|
2159
3064
|
for (const topic of startup.topics) {
|
|
2160
|
-
await
|
|
3065
|
+
await activeTransport.joinTopic(topic);
|
|
2161
3066
|
}
|
|
2162
3067
|
for (const did of startup.connectDids) {
|
|
2163
|
-
await
|
|
3068
|
+
await activeTransport.connectToDid(did);
|
|
2164
3069
|
}
|
|
2165
3070
|
for (const publicKey of startup.connectNoiseKeys) {
|
|
2166
|
-
await
|
|
3071
|
+
await activeTransport.connectToNoiseKey(publicKey);
|
|
2167
3072
|
}
|
|
2168
3073
|
if (startup.watchProtocol) {
|
|
2169
3074
|
discoveryInterval = setInterval(() => {
|
|
2170
|
-
void runProtocolDiscoveryWatcher(
|
|
3075
|
+
void runProtocolDiscoveryWatcher(activeTransport, seenControlLengths, io).catch((error) => {
|
|
2171
3076
|
io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
2172
3077
|
});
|
|
2173
3078
|
}, 2_000);
|
|
2174
3079
|
}
|
|
3080
|
+
walletPollInterval = setInterval(() => {
|
|
3081
|
+
if (walletPollRunning) {
|
|
3082
|
+
return;
|
|
3083
|
+
}
|
|
3084
|
+
walletPollRunning = true;
|
|
3085
|
+
void (async () => {
|
|
3086
|
+
try {
|
|
3087
|
+
await walletService.pollUpdates();
|
|
3088
|
+
walletStatus = await walletService.daemonStatus();
|
|
3089
|
+
}
|
|
3090
|
+
catch (error) {
|
|
3091
|
+
io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
3092
|
+
}
|
|
3093
|
+
finally {
|
|
3094
|
+
walletPollRunning = false;
|
|
3095
|
+
}
|
|
3096
|
+
})();
|
|
3097
|
+
}, 3_000);
|
|
3098
|
+
autoSettleInterval = setInterval(() => {
|
|
3099
|
+
if (autoSettleRunning || !sharedContext) {
|
|
3100
|
+
return;
|
|
3101
|
+
}
|
|
3102
|
+
autoSettleRunning = true;
|
|
3103
|
+
void (async () => {
|
|
3104
|
+
try {
|
|
3105
|
+
const candidates = collectAutoSettleCandidates(sharedContext.repository.getSnapshot());
|
|
3106
|
+
for (const candidate of candidates) {
|
|
3107
|
+
await walletService.attemptAutoSettle(candidate);
|
|
3108
|
+
}
|
|
3109
|
+
walletStatus = await walletService.daemonStatus();
|
|
3110
|
+
}
|
|
3111
|
+
catch (error) {
|
|
3112
|
+
io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
3113
|
+
}
|
|
3114
|
+
finally {
|
|
3115
|
+
autoSettleRunning = false;
|
|
3116
|
+
}
|
|
3117
|
+
})();
|
|
3118
|
+
}, 2_000);
|
|
2175
3119
|
daemon = new AgentDaemon({
|
|
2176
3120
|
dataDir,
|
|
2177
|
-
statusProvider: () => buildDaemonStatus(dataDir, startedAt,
|
|
3121
|
+
statusProvider: () => buildDaemonStatus(dataDir, startedAt, activeTransport, walletStatus),
|
|
2178
3122
|
commandHandler: async (request) => {
|
|
2179
3123
|
if (!sharedContext) {
|
|
2180
3124
|
throw new Error("Daemon context is not available");
|
|
2181
3125
|
}
|
|
2182
|
-
|
|
3126
|
+
const result = await CLI_CONTEXT_STORAGE.run(sharedContext, async () => executeCapturedInDaemon({
|
|
2183
3127
|
commandPath: request.commandPath,
|
|
2184
3128
|
options: daemonOptionsRecordToMap(request.options)
|
|
2185
3129
|
}));
|
|
3130
|
+
walletStatus = await walletService.daemonStatus();
|
|
3131
|
+
return result;
|
|
2186
3132
|
},
|
|
2187
3133
|
onShutdown: async () => {
|
|
2188
3134
|
if (discoveryInterval) {
|
|
2189
3135
|
clearInterval(discoveryInterval);
|
|
2190
3136
|
discoveryInterval = undefined;
|
|
2191
3137
|
}
|
|
3138
|
+
if (walletPollInterval) {
|
|
3139
|
+
clearInterval(walletPollInterval);
|
|
3140
|
+
walletPollInterval = undefined;
|
|
3141
|
+
}
|
|
3142
|
+
if (autoSettleInterval) {
|
|
3143
|
+
clearInterval(autoSettleInterval);
|
|
3144
|
+
autoSettleInterval = undefined;
|
|
3145
|
+
}
|
|
2192
3146
|
if (sharedContext) {
|
|
2193
3147
|
await sharedContext.repository.close();
|
|
2194
3148
|
sharedContext = undefined;
|
|
2195
3149
|
}
|
|
2196
|
-
await
|
|
3150
|
+
await walletService.close();
|
|
3151
|
+
await activeTransport.stop();
|
|
2197
3152
|
}
|
|
2198
3153
|
});
|
|
2199
3154
|
await daemon.start();
|
|
@@ -2208,10 +3163,19 @@ async function handleDaemonRun(args, io) {
|
|
|
2208
3163
|
if (discoveryInterval) {
|
|
2209
3164
|
clearInterval(discoveryInterval);
|
|
2210
3165
|
}
|
|
3166
|
+
if (walletPollInterval) {
|
|
3167
|
+
clearInterval(walletPollInterval);
|
|
3168
|
+
}
|
|
3169
|
+
if (autoSettleInterval) {
|
|
3170
|
+
clearInterval(autoSettleInterval);
|
|
3171
|
+
}
|
|
2211
3172
|
if (sharedContext) {
|
|
2212
3173
|
await sharedContext.repository.close();
|
|
2213
3174
|
}
|
|
2214
|
-
await
|
|
3175
|
+
await walletService.close();
|
|
3176
|
+
if (transport) {
|
|
3177
|
+
await transport.stop();
|
|
3178
|
+
}
|
|
2215
3179
|
}
|
|
2216
3180
|
}
|
|
2217
3181
|
}
|
|
@@ -2220,180 +3184,229 @@ async function executeParsedArgs(args, io, options) {
|
|
|
2220
3184
|
io.stdout(`${usage()}\n`);
|
|
2221
3185
|
return 0;
|
|
2222
3186
|
}
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
3187
|
+
const resolvedArgs = await withResolvedDataDir(args);
|
|
3188
|
+
if (commandMatches(resolvedArgs.commandPath, "daemon", "start"))
|
|
3189
|
+
return await handleDaemonStart(resolvedArgs, io).then(() => 0);
|
|
3190
|
+
if (commandMatches(resolvedArgs.commandPath, "daemon", "status"))
|
|
3191
|
+
return await handleDaemonStatus(resolvedArgs, io).then(() => 0);
|
|
3192
|
+
if (commandMatches(resolvedArgs.commandPath, "daemon", "stop"))
|
|
3193
|
+
return await handleDaemonStop(resolvedArgs, io).then(() => 0);
|
|
3194
|
+
if (commandMatches(resolvedArgs.commandPath, "daemon", "logs"))
|
|
3195
|
+
return await handleDaemonLogs(resolvedArgs, io).then(() => 0);
|
|
3196
|
+
if (commandMatches(resolvedArgs.commandPath, "daemon", "run"))
|
|
3197
|
+
return await handleDaemonRun(resolvedArgs, io).then(() => 0);
|
|
2233
3198
|
if (options.allowDaemonProxy) {
|
|
2234
|
-
const dataDir = getDataDirFromArgs(
|
|
3199
|
+
const dataDir = getDataDirFromArgs(resolvedArgs);
|
|
2235
3200
|
if (dataDir) {
|
|
2236
3201
|
const activeDaemon = await probeDaemonStatus(dataDir, 1_000);
|
|
2237
3202
|
if (activeDaemon) {
|
|
2238
|
-
return proxyParsedArgsToDaemon(
|
|
3203
|
+
return proxyParsedArgsToDaemon(withDaemonWalletKeyForwarding(resolvedArgs), io);
|
|
2239
3204
|
}
|
|
2240
3205
|
}
|
|
2241
3206
|
}
|
|
2242
|
-
if (commandMatches(
|
|
2243
|
-
return await
|
|
2244
|
-
if (commandMatches(
|
|
2245
|
-
return await
|
|
2246
|
-
if (commandMatches(
|
|
2247
|
-
return await
|
|
2248
|
-
if (commandMatches(
|
|
2249
|
-
return await
|
|
2250
|
-
if (commandMatches(
|
|
2251
|
-
return await
|
|
2252
|
-
if (commandMatches(
|
|
2253
|
-
return await
|
|
2254
|
-
if (commandMatches(
|
|
2255
|
-
return await
|
|
2256
|
-
if (commandMatches(
|
|
2257
|
-
return await
|
|
2258
|
-
if (commandMatches(
|
|
2259
|
-
return await
|
|
2260
|
-
if (commandMatches(
|
|
2261
|
-
return await
|
|
2262
|
-
if (commandMatches(
|
|
2263
|
-
return await
|
|
2264
|
-
if (commandMatches(
|
|
2265
|
-
return await
|
|
2266
|
-
if (commandMatches(
|
|
2267
|
-
return await
|
|
2268
|
-
if (commandMatches(
|
|
2269
|
-
return await
|
|
2270
|
-
if (commandMatches(
|
|
2271
|
-
return await
|
|
2272
|
-
if (commandMatches(
|
|
2273
|
-
return await
|
|
2274
|
-
if (commandMatches(
|
|
2275
|
-
return await
|
|
2276
|
-
if (commandMatches(
|
|
2277
|
-
return await
|
|
2278
|
-
if (commandMatches(
|
|
2279
|
-
return await
|
|
2280
|
-
if (commandMatches(
|
|
2281
|
-
return await
|
|
2282
|
-
if (commandMatches(
|
|
2283
|
-
return await
|
|
2284
|
-
if (commandMatches(
|
|
2285
|
-
return await
|
|
2286
|
-
if (commandMatches(
|
|
2287
|
-
return await
|
|
2288
|
-
if (commandMatches(
|
|
2289
|
-
return await
|
|
2290
|
-
if (commandMatches(
|
|
2291
|
-
return await
|
|
2292
|
-
if (commandMatches(
|
|
2293
|
-
return await
|
|
2294
|
-
if (commandMatches(
|
|
2295
|
-
return await
|
|
2296
|
-
if (commandMatches(
|
|
2297
|
-
return await
|
|
2298
|
-
if (commandMatches(
|
|
2299
|
-
return await
|
|
2300
|
-
if (commandMatches(
|
|
2301
|
-
return await
|
|
2302
|
-
if (commandMatches(
|
|
2303
|
-
return await
|
|
2304
|
-
if (commandMatches(
|
|
2305
|
-
return await
|
|
2306
|
-
if (commandMatches(
|
|
2307
|
-
return await
|
|
2308
|
-
if (commandMatches(
|
|
2309
|
-
return await
|
|
2310
|
-
if (commandMatches(
|
|
2311
|
-
return await
|
|
2312
|
-
if (commandMatches(
|
|
2313
|
-
return await
|
|
2314
|
-
if (commandMatches(
|
|
2315
|
-
return await
|
|
2316
|
-
if (commandMatches(
|
|
2317
|
-
return await
|
|
2318
|
-
if (commandMatches(
|
|
2319
|
-
return await
|
|
2320
|
-
if (commandMatches(
|
|
2321
|
-
return await
|
|
2322
|
-
if (commandMatches(
|
|
2323
|
-
return await
|
|
2324
|
-
if (commandMatches(
|
|
2325
|
-
return await
|
|
2326
|
-
if (commandMatches(
|
|
2327
|
-
return await
|
|
2328
|
-
if (commandMatches(
|
|
2329
|
-
return await
|
|
2330
|
-
if (commandMatches(
|
|
2331
|
-
return await
|
|
2332
|
-
if (commandMatches(
|
|
2333
|
-
return await
|
|
2334
|
-
if (commandMatches(
|
|
2335
|
-
return await
|
|
2336
|
-
if (commandMatches(
|
|
2337
|
-
return await
|
|
2338
|
-
if (commandMatches(
|
|
2339
|
-
return await
|
|
2340
|
-
if (commandMatches(
|
|
2341
|
-
return await
|
|
2342
|
-
if (commandMatches(
|
|
2343
|
-
return await
|
|
2344
|
-
if (commandMatches(
|
|
2345
|
-
return await
|
|
2346
|
-
if (commandMatches(
|
|
2347
|
-
return await
|
|
2348
|
-
if (commandMatches(
|
|
2349
|
-
return await
|
|
2350
|
-
if (commandMatches(
|
|
2351
|
-
return await
|
|
2352
|
-
if (commandMatches(
|
|
2353
|
-
return await
|
|
2354
|
-
if (commandMatches(
|
|
2355
|
-
return await
|
|
2356
|
-
if (commandMatches(
|
|
2357
|
-
return await
|
|
2358
|
-
if (commandMatches(
|
|
2359
|
-
return await
|
|
2360
|
-
if (commandMatches(
|
|
2361
|
-
return await
|
|
2362
|
-
if (commandMatches(
|
|
2363
|
-
return await
|
|
2364
|
-
if (commandMatches(
|
|
2365
|
-
return await
|
|
2366
|
-
if (commandMatches(
|
|
2367
|
-
return await
|
|
2368
|
-
if (commandMatches(
|
|
2369
|
-
return await
|
|
2370
|
-
if (commandMatches(
|
|
2371
|
-
return await
|
|
2372
|
-
if (commandMatches(
|
|
2373
|
-
return await
|
|
2374
|
-
if (commandMatches(
|
|
2375
|
-
return await
|
|
2376
|
-
if (commandMatches(
|
|
2377
|
-
return await
|
|
2378
|
-
if (commandMatches(
|
|
2379
|
-
return await
|
|
2380
|
-
if (commandMatches(
|
|
2381
|
-
return await
|
|
2382
|
-
if (commandMatches(
|
|
2383
|
-
return await
|
|
2384
|
-
if (commandMatches(
|
|
2385
|
-
return await
|
|
2386
|
-
if (commandMatches(
|
|
2387
|
-
return await
|
|
2388
|
-
if (commandMatches(
|
|
2389
|
-
return await
|
|
2390
|
-
if (commandMatches(
|
|
2391
|
-
return await
|
|
2392
|
-
if (commandMatches(
|
|
2393
|
-
return await
|
|
2394
|
-
if (commandMatches(
|
|
2395
|
-
return await
|
|
2396
|
-
|
|
3207
|
+
if (commandMatches(resolvedArgs.commandPath, "context", "add"))
|
|
3208
|
+
return await handleContextAdd(resolvedArgs, io).then(() => 0);
|
|
3209
|
+
if (commandMatches(resolvedArgs.commandPath, "context", "use"))
|
|
3210
|
+
return await handleContextUse(resolvedArgs, io).then(() => 0);
|
|
3211
|
+
if (commandMatches(resolvedArgs.commandPath, "context", "list"))
|
|
3212
|
+
return await handleContextList(io).then(() => 0);
|
|
3213
|
+
if (commandMatches(resolvedArgs.commandPath, "context", "show"))
|
|
3214
|
+
return await handleContextShow(io).then(() => 0);
|
|
3215
|
+
if (commandMatches(resolvedArgs.commandPath, "context", "remove"))
|
|
3216
|
+
return await handleContextRemove(resolvedArgs, io).then(() => 0);
|
|
3217
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "init"))
|
|
3218
|
+
return await handleAgentInit(resolvedArgs, io).then(() => 0);
|
|
3219
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "connect", "nwc"))
|
|
3220
|
+
return await handleWalletConnectNwc(resolvedArgs, io).then(() => 0);
|
|
3221
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "disconnect"))
|
|
3222
|
+
return await handleWalletDisconnect(resolvedArgs, io).then(() => 0);
|
|
3223
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "status"))
|
|
3224
|
+
return await handleWalletStatus(resolvedArgs, io).then(() => 0);
|
|
3225
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "unlock"))
|
|
3226
|
+
return await handleWalletUnlock(resolvedArgs, io).then(() => 0);
|
|
3227
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "lock"))
|
|
3228
|
+
return await handleWalletLock(resolvedArgs, io).then(() => 0);
|
|
3229
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "invoice", "create"))
|
|
3230
|
+
return await handleWalletInvoiceCreate(resolvedArgs, io).then(() => 0);
|
|
3231
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "pay", "bolt11"))
|
|
3232
|
+
return await handleWalletPayBolt11(resolvedArgs, io).then(() => 0);
|
|
3233
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "ledger", "list"))
|
|
3234
|
+
return await handleWalletLedgerList(resolvedArgs, io).then(() => 0);
|
|
3235
|
+
if (commandMatches(resolvedArgs.commandPath, "wallet", "key", "rotate"))
|
|
3236
|
+
return await handleWalletKeyRotate(resolvedArgs, io).then(() => 0);
|
|
3237
|
+
if (commandMatches(resolvedArgs.commandPath, "deal", "open"))
|
|
3238
|
+
return await handleDealOpen(resolvedArgs, io).then(() => 0);
|
|
3239
|
+
if (commandMatches(resolvedArgs.commandPath, "deal", "propose"))
|
|
3240
|
+
return await handleDealPropose(resolvedArgs, io).then(() => 0);
|
|
3241
|
+
if (commandMatches(resolvedArgs.commandPath, "deal", "accept"))
|
|
3242
|
+
return await handleDealAccept(resolvedArgs, io).then(() => 0);
|
|
3243
|
+
if (commandMatches(resolvedArgs.commandPath, "deal", "start"))
|
|
3244
|
+
return await handleDealStart(resolvedArgs, io).then(() => 0);
|
|
3245
|
+
if (commandMatches(resolvedArgs.commandPath, "deal", "status"))
|
|
3246
|
+
return await handleDealStatus(resolvedArgs, io).then(() => 0);
|
|
3247
|
+
if (commandMatches(resolvedArgs.commandPath, "proof", "submit"))
|
|
3248
|
+
return await handleProofSubmit(resolvedArgs, io).then(() => 0);
|
|
3249
|
+
if (commandMatches(resolvedArgs.commandPath, "proof", "accept"))
|
|
3250
|
+
return await handleProofAccept(resolvedArgs, io).then(() => 0);
|
|
3251
|
+
if (commandMatches(resolvedArgs.commandPath, "settlement", "invoice", "create"))
|
|
3252
|
+
return await handleSettlementInvoiceCreate(resolvedArgs, io).then(() => 0);
|
|
3253
|
+
if (commandMatches(resolvedArgs.commandPath, "settlement", "pay"))
|
|
3254
|
+
return await handleSettlementPay(resolvedArgs, io).then(() => 0);
|
|
3255
|
+
if (commandMatches(resolvedArgs.commandPath, "settlement", "status"))
|
|
3256
|
+
return await handleSettlementStatus(resolvedArgs, io).then(() => 0);
|
|
3257
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "show"))
|
|
3258
|
+
return await handleAgentShow(resolvedArgs, io).then(() => 0);
|
|
3259
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "payment-endpoint", "add"))
|
|
3260
|
+
return await handleAgentPaymentEndpointAdd(resolvedArgs, io).then(() => 0);
|
|
3261
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "payment-endpoint", "remove"))
|
|
3262
|
+
return await handleAgentPaymentEndpointRemove(resolvedArgs, io).then(() => 0);
|
|
3263
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "wallet-attestation", "add"))
|
|
3264
|
+
return await handleAgentWalletAttestationAdd(resolvedArgs, io).then(() => 0);
|
|
3265
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "wallet-attestation", "remove"))
|
|
3266
|
+
return await handleAgentWalletAttestationRemove(resolvedArgs, io).then(() => 0);
|
|
3267
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "feedback", "add"))
|
|
3268
|
+
return await handleAgentFeedbackAdd(resolvedArgs, io).then(() => 0);
|
|
3269
|
+
if (commandMatches(resolvedArgs.commandPath, "agent", "feedback", "remove"))
|
|
3270
|
+
return await handleAgentFeedbackRemove(resolvedArgs, io).then(() => 0);
|
|
3271
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "create"))
|
|
3272
|
+
return await handleCompanyCreate(resolvedArgs, io).then(() => 0);
|
|
3273
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "show"))
|
|
3274
|
+
return await handleCompanyShow(resolvedArgs, io).then(() => 0);
|
|
3275
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "update"))
|
|
3276
|
+
return await handleCompanyUpdate(resolvedArgs, io).then(() => 0);
|
|
3277
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "grant-role"))
|
|
3278
|
+
return await handleCompanyRoleChange(resolvedArgs, io, "grant").then(() => 0);
|
|
3279
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "revoke-role"))
|
|
3280
|
+
return await handleCompanyRoleChange(resolvedArgs, io, "revoke").then(() => 0);
|
|
3281
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "join-market"))
|
|
3282
|
+
return await handleCompanyMarketMembership(resolvedArgs, io, "join").then(() => 0);
|
|
3283
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "leave-market"))
|
|
3284
|
+
return await handleCompanyMarketMembership(resolvedArgs, io, "leave").then(() => 0);
|
|
3285
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "treasury-attest"))
|
|
3286
|
+
return await handleCompanyTreasuryAttest(resolvedArgs, io).then(() => 0);
|
|
3287
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "treasury-reserve"))
|
|
3288
|
+
return await handleCompanyTreasuryReserve(resolvedArgs, io).then(() => 0);
|
|
3289
|
+
if (commandMatches(resolvedArgs.commandPath, "company", "treasury-release"))
|
|
3290
|
+
return await handleCompanyTreasuryRelease(resolvedArgs, io).then(() => 0);
|
|
3291
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "product", "create"))
|
|
3292
|
+
return await handleMarketProductCreate(resolvedArgs, io).then(() => 0);
|
|
3293
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "product", "update"))
|
|
3294
|
+
return await handleMarketProductUpdate(resolvedArgs, io).then(() => 0);
|
|
3295
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "product", "publish"))
|
|
3296
|
+
return await handleMarketProductStateChange(resolvedArgs, io, "product.published").then(() => 0);
|
|
3297
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "product", "unpublish"))
|
|
3298
|
+
return await handleMarketProductStateChange(resolvedArgs, io, "product.unpublished").then(() => 0);
|
|
3299
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "product", "retire"))
|
|
3300
|
+
return await handleMarketProductStateChange(resolvedArgs, io, "product.retired").then(() => 0);
|
|
3301
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "listing", "publish"))
|
|
3302
|
+
return await handleMarketListingPublish(resolvedArgs, io).then(() => 0);
|
|
3303
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "listing", "revise"))
|
|
3304
|
+
return await handleMarketListingRevise(resolvedArgs, io).then(() => 0);
|
|
3305
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "listing", "withdraw"))
|
|
3306
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "listing", "listing.withdrawn").then(() => 0);
|
|
3307
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "listing", "expire"))
|
|
3308
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "listing", "listing.expired").then(() => 0);
|
|
3309
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "request", "publish"))
|
|
3310
|
+
return await handleMarketRequestPublish(resolvedArgs, io).then(() => 0);
|
|
3311
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "request", "revise"))
|
|
3312
|
+
return await handleMarketRequestRevise(resolvedArgs, io).then(() => 0);
|
|
3313
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "request", "close"))
|
|
3314
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "request", "request.closed").then(() => 0);
|
|
3315
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "request", "expire"))
|
|
3316
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "request", "request.expired").then(() => 0);
|
|
3317
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "offer", "submit"))
|
|
3318
|
+
return await handleMarketOfferSubmit(resolvedArgs, io).then(() => 0);
|
|
3319
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "offer", "counter"))
|
|
3320
|
+
return await handleMarketOfferCounter(resolvedArgs, io).then(() => 0);
|
|
3321
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "offer", "accept"))
|
|
3322
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "offer", "offer.accepted").then(() => 0);
|
|
3323
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "offer", "reject"))
|
|
3324
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "offer", "offer.rejected").then(() => 0);
|
|
3325
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "offer", "cancel"))
|
|
3326
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "offer", "offer.canceled").then(() => 0);
|
|
3327
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "offer", "expire"))
|
|
3328
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "offer", "offer.expired").then(() => 0);
|
|
3329
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "bid", "submit"))
|
|
3330
|
+
return await handleMarketBidSubmit(resolvedArgs, io).then(() => 0);
|
|
3331
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "bid", "counter"))
|
|
3332
|
+
return await handleMarketBidCounter(resolvedArgs, io).then(() => 0);
|
|
3333
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "bid", "accept"))
|
|
3334
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "bid", "bid.accepted").then(() => 0);
|
|
3335
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "bid", "reject"))
|
|
3336
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "bid", "bid.rejected").then(() => 0);
|
|
3337
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "bid", "cancel"))
|
|
3338
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "bid", "bid.canceled").then(() => 0);
|
|
3339
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "bid", "expire"))
|
|
3340
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "bid", "bid.expired").then(() => 0);
|
|
3341
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "agreement", "create"))
|
|
3342
|
+
return await handleMarketAgreementCreate(resolvedArgs, io).then(() => 0);
|
|
3343
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "agreement", "complete"))
|
|
3344
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "agreement", "agreement.completed").then(() => 0);
|
|
3345
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "agreement", "cancel"))
|
|
3346
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "agreement", "agreement.canceled").then(() => 0);
|
|
3347
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "agreement", "dispute"))
|
|
3348
|
+
return await handleSimpleMarketStateChange(resolvedArgs, io, "agreement", "agreement.disputed").then(() => 0);
|
|
3349
|
+
if (commandMatches(resolvedArgs.commandPath, "market", "list"))
|
|
3350
|
+
return await handleMarketList(resolvedArgs, io).then(() => 0);
|
|
3351
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "create"))
|
|
3352
|
+
return await handleContractCreate(resolvedArgs, io).then(() => 0);
|
|
3353
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "open-milestone"))
|
|
3354
|
+
return await handleContractMilestoneAction(resolvedArgs, io, "contract.milestone-opened").then(() => 0);
|
|
3355
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "submit-milestone"))
|
|
3356
|
+
return await handleContractMilestoneAction(resolvedArgs, io, "contract.milestone-submitted").then(() => 0);
|
|
3357
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "accept-milestone"))
|
|
3358
|
+
return await handleContractMilestoneAction(resolvedArgs, io, "contract.milestone-accepted").then(() => 0);
|
|
3359
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "reject-milestone"))
|
|
3360
|
+
return await handleContractMilestoneAction(resolvedArgs, io, "contract.milestone-rejected").then(() => 0);
|
|
3361
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "pause"))
|
|
3362
|
+
return await handleContractStateChange(resolvedArgs, io, "contract.paused").then(() => 0);
|
|
3363
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "resume"))
|
|
3364
|
+
return await handleContractStateChange(resolvedArgs, io, "contract.resumed").then(() => 0);
|
|
3365
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "complete"))
|
|
3366
|
+
return await handleContractStateChange(resolvedArgs, io, "contract.completed").then(() => 0);
|
|
3367
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "cancel"))
|
|
3368
|
+
return await handleContractStateChange(resolvedArgs, io, "contract.canceled").then(() => 0);
|
|
3369
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "dispute"))
|
|
3370
|
+
return await handleContractStateChange(resolvedArgs, io, "contract.disputed").then(() => 0);
|
|
3371
|
+
if (commandMatches(resolvedArgs.commandPath, "contract", "entries"))
|
|
3372
|
+
return await handleContractEntries(resolvedArgs, io).then(() => 0);
|
|
3373
|
+
if (commandMatches(resolvedArgs.commandPath, "evidence", "record"))
|
|
3374
|
+
return await handleEvidenceRecord(resolvedArgs, io).then(() => 0);
|
|
3375
|
+
if (commandMatches(resolvedArgs.commandPath, "oracle", "attest"))
|
|
3376
|
+
return await handleOracleAttest(resolvedArgs, io).then(() => 0);
|
|
3377
|
+
if (commandMatches(resolvedArgs.commandPath, "dispute", "open"))
|
|
3378
|
+
return await handleDisputeOpen(resolvedArgs, io).then(() => 0);
|
|
3379
|
+
if (commandMatches(resolvedArgs.commandPath, "dispute", "add-evidence"))
|
|
3380
|
+
return await handleDisputeAddEvidence(resolvedArgs, io).then(() => 0);
|
|
3381
|
+
if (commandMatches(resolvedArgs.commandPath, "dispute", "request-oracle"))
|
|
3382
|
+
return await handleDisputeRequestOracle(resolvedArgs, io).then(() => 0);
|
|
3383
|
+
if (commandMatches(resolvedArgs.commandPath, "dispute", "rule"))
|
|
3384
|
+
return await handleDisputeRule(resolvedArgs, io).then(() => 0);
|
|
3385
|
+
if (commandMatches(resolvedArgs.commandPath, "dispute", "close"))
|
|
3386
|
+
return await handleDisputeClose(resolvedArgs, io).then(() => 0);
|
|
3387
|
+
if (commandMatches(resolvedArgs.commandPath, "space", "create"))
|
|
3388
|
+
return await handleSpaceCreate(resolvedArgs, io).then(() => 0);
|
|
3389
|
+
if (commandMatches(resolvedArgs.commandPath, "space", "add-member"))
|
|
3390
|
+
return await handleSpaceMembershipAction(resolvedArgs, io, "space-membership.member-added").then(() => 0);
|
|
3391
|
+
if (commandMatches(resolvedArgs.commandPath, "space", "remove-member"))
|
|
3392
|
+
return await handleSpaceMembershipAction(resolvedArgs, io, "space-membership.member-removed").then(() => 0);
|
|
3393
|
+
if (commandMatches(resolvedArgs.commandPath, "space", "mute-member"))
|
|
3394
|
+
return await handleSpaceMembershipAction(resolvedArgs, io, "space-membership.member-muted").then(() => 0);
|
|
3395
|
+
if (commandMatches(resolvedArgs.commandPath, "space", "set-role"))
|
|
3396
|
+
return await handleSpaceMembershipAction(resolvedArgs, io, "space-membership.member-role-updated").then(() => 0);
|
|
3397
|
+
if (commandMatches(resolvedArgs.commandPath, "space", "entries"))
|
|
3398
|
+
return await handleSpaceEntries(resolvedArgs, io).then(() => 0);
|
|
3399
|
+
if (commandMatches(resolvedArgs.commandPath, "message", "send"))
|
|
3400
|
+
return await handleMessageSend(resolvedArgs, io).then(() => 0);
|
|
3401
|
+
if (commandMatches(resolvedArgs.commandPath, "message", "edit"))
|
|
3402
|
+
return await handleMessageEdit(resolvedArgs, io).then(() => 0);
|
|
3403
|
+
if (commandMatches(resolvedArgs.commandPath, "message", "delete"))
|
|
3404
|
+
return await handleMessageDelete(resolvedArgs, io).then(() => 0);
|
|
3405
|
+
if (commandMatches(resolvedArgs.commandPath, "message", "react"))
|
|
3406
|
+
return await handleMessageReact(resolvedArgs, io).then(() => 0);
|
|
3407
|
+
if (commandMatches(resolvedArgs.commandPath, "object", "show"))
|
|
3408
|
+
return await handleObjectShow(resolvedArgs, io).then(() => 0);
|
|
3409
|
+
throw new Error(`Unknown command: ${resolvedArgs.commandPath.join(" ")}`);
|
|
2397
3410
|
}
|
|
2398
3411
|
export async function runCli(argv, io = DEFAULT_IO) {
|
|
2399
3412
|
try {
|