@garydevenay/emporion 0.0.1
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/LICENSE +21 -0
- package/README.md +173 -0
- package/dist/src/cli.d.ts +7 -0
- package/dist/src/cli.js +2101 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.d.ts +2 -0
- package/dist/src/config.js +41 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/demo.d.ts +1 -0
- package/dist/src/demo.js +140 -0
- package/dist/src/demo.js.map +1 -0
- package/dist/src/did.d.ts +13 -0
- package/dist/src/did.js +155 -0
- package/dist/src/did.js.map +1 -0
- package/dist/src/errors.d.ts +23 -0
- package/dist/src/errors.js +25 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/handshake.d.ts +9 -0
- package/dist/src/handshake.js +131 -0
- package/dist/src/handshake.js.map +1 -0
- package/dist/src/identity.d.ts +17 -0
- package/dist/src/identity.js +105 -0
- package/dist/src/identity.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logger.d.ts +11 -0
- package/dist/src/logger.js +41 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/persistent-agent.d.ts +2 -0
- package/dist/src/persistent-agent.js +24 -0
- package/dist/src/persistent-agent.js.map +1 -0
- package/dist/src/protocol/company.d.ts +36 -0
- package/dist/src/protocol/company.js +211 -0
- package/dist/src/protocol/company.js.map +1 -0
- package/dist/src/protocol/contracts.d.ts +119 -0
- package/dist/src/protocol/contracts.js +404 -0
- package/dist/src/protocol/contracts.js.map +1 -0
- package/dist/src/protocol/credential-reference.d.ts +71 -0
- package/dist/src/protocol/credential-reference.js +136 -0
- package/dist/src/protocol/credential-reference.js.map +1 -0
- package/dist/src/protocol/dissemination.d.ts +47 -0
- package/dist/src/protocol/dissemination.js +111 -0
- package/dist/src/protocol/dissemination.js.map +1 -0
- package/dist/src/protocol/envelope.d.ts +71 -0
- package/dist/src/protocol/envelope.js +203 -0
- package/dist/src/protocol/envelope.js.map +1 -0
- package/dist/src/protocol/identity.d.ts +18 -0
- package/dist/src/protocol/identity.js +143 -0
- package/dist/src/protocol/identity.js.map +1 -0
- package/dist/src/protocol/index.d.ts +22 -0
- package/dist/src/protocol/index.js +12 -0
- package/dist/src/protocol/index.js.map +1 -0
- package/dist/src/protocol/market.d.ts +96 -0
- package/dist/src/protocol/market.js +293 -0
- package/dist/src/protocol/market.js.map +1 -0
- package/dist/src/protocol/messaging.d.ts +87 -0
- package/dist/src/protocol/messaging.js +296 -0
- package/dist/src/protocol/messaging.js.map +1 -0
- package/dist/src/protocol/repository.d.ts +87 -0
- package/dist/src/protocol/repository.js +651 -0
- package/dist/src/protocol/repository.js.map +1 -0
- package/dist/src/protocol/resolution.d.ts +86 -0
- package/dist/src/protocol/resolution.js +305 -0
- package/dist/src/protocol/resolution.js.map +1 -0
- package/dist/src/protocol/shared.d.ts +14 -0
- package/dist/src/protocol/shared.js +45 -0
- package/dist/src/protocol/shared.js.map +1 -0
- package/dist/src/protocol/versioning.d.ts +21 -0
- package/dist/src/protocol/versioning.js +69 -0
- package/dist/src/protocol/versioning.js.map +1 -0
- package/dist/src/storage.d.ts +36 -0
- package/dist/src/storage.js +156 -0
- package/dist/src/storage.js.map +1 -0
- package/dist/src/topics.d.ts +3 -0
- package/dist/src/topics.js +27 -0
- package/dist/src/topics.js.map +1 -0
- package/dist/src/transport.d.ts +114 -0
- package/dist/src/transport.js +291 -0
- package/dist/src/transport.js.map +1 -0
- package/dist/src/types.d.ts +95 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/test/cli.test.d.ts +1 -0
- package/dist/test/cli.test.js +122 -0
- package/dist/test/cli.test.js.map +1 -0
- package/dist/test/economy.test.d.ts +1 -0
- package/dist/test/economy.test.js +661 -0
- package/dist/test/economy.test.js.map +1 -0
- package/dist/test/helpers.d.ts +12 -0
- package/dist/test/helpers.js +57 -0
- package/dist/test/helpers.js.map +1 -0
- package/dist/test/integration.test.d.ts +1 -0
- package/dist/test/integration.test.js +287 -0
- package/dist/test/integration.test.js.map +1 -0
- package/dist/test/protocol.test.d.ts +1 -0
- package/dist/test/protocol.test.js +448 -0
- package/dist/test/protocol.test.js.map +1 -0
- package/dist/test/unit.test.d.ts +1 -0
- package/dist/test/unit.test.js +87 -0
- package/dist/test/unit.test.js.map +1 -0
- package/package.json +60 -0
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,2101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { once } from "node:events";
|
|
3
|
+
import { AgentTransport } from "./transport.js";
|
|
4
|
+
import { createLogger } from "./logger.js";
|
|
5
|
+
import { loadPersistentIdentityMaterial } from "./persistent-agent.js";
|
|
6
|
+
import * as Protocol from "./protocol/index.js";
|
|
7
|
+
import { sha256Hex } from "./protocol/shared.js";
|
|
8
|
+
import { TransportStorage } from "./storage.js";
|
|
9
|
+
const DEFAULT_IO = {
|
|
10
|
+
stdout(message) {
|
|
11
|
+
process.stdout.write(message);
|
|
12
|
+
},
|
|
13
|
+
stderr(message) {
|
|
14
|
+
process.stderr.write(message);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
function parseArgs(argv) {
|
|
18
|
+
const commandPath = [];
|
|
19
|
+
const options = new Map();
|
|
20
|
+
let index = 0;
|
|
21
|
+
while (index < argv.length && !argv[index]?.startsWith("--")) {
|
|
22
|
+
commandPath.push(argv[index]);
|
|
23
|
+
index += 1;
|
|
24
|
+
}
|
|
25
|
+
while (index < argv.length) {
|
|
26
|
+
const token = argv[index];
|
|
27
|
+
if (!token?.startsWith("--")) {
|
|
28
|
+
throw new Error(`Unexpected positional argument: ${token ?? ""}`);
|
|
29
|
+
}
|
|
30
|
+
const optionName = token.slice(2);
|
|
31
|
+
if (optionName.length === 0) {
|
|
32
|
+
throw new Error("Option names must not be blank");
|
|
33
|
+
}
|
|
34
|
+
const nextToken = argv[index + 1];
|
|
35
|
+
const value = !nextToken || nextToken.startsWith("--") ? "true" : nextToken;
|
|
36
|
+
const existing = options.get(optionName) ?? [];
|
|
37
|
+
existing.push(value);
|
|
38
|
+
options.set(optionName, existing);
|
|
39
|
+
index += value === "true" ? 1 : 2;
|
|
40
|
+
}
|
|
41
|
+
return { commandPath, options };
|
|
42
|
+
}
|
|
43
|
+
function commandMatches(commandPath, ...expected) {
|
|
44
|
+
return commandPath.length === expected.length && expected.every((value, index) => commandPath[index] === value);
|
|
45
|
+
}
|
|
46
|
+
function getOptionValues(args, name) {
|
|
47
|
+
return args.options.get(name) ?? [];
|
|
48
|
+
}
|
|
49
|
+
function hasFlag(args, name) {
|
|
50
|
+
return getOptionValues(args, name).includes("true");
|
|
51
|
+
}
|
|
52
|
+
function getOptionalOption(args, name) {
|
|
53
|
+
const values = getOptionValues(args, name).filter((value) => value !== "true");
|
|
54
|
+
return values.at(-1);
|
|
55
|
+
}
|
|
56
|
+
function requireOption(args, name) {
|
|
57
|
+
const value = getOptionalOption(args, name);
|
|
58
|
+
if (!value || value.trim().length === 0) {
|
|
59
|
+
throw new Error(`Missing required option --${name}`);
|
|
60
|
+
}
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
function getCsvOptionValues(args, name) {
|
|
64
|
+
return getOptionValues(args, name)
|
|
65
|
+
.flatMap((value) => value.split(","))
|
|
66
|
+
.map((value) => value.trim())
|
|
67
|
+
.filter((value) => value.length > 0 && value !== "true");
|
|
68
|
+
}
|
|
69
|
+
function parsePositiveInteger(value, fieldName) {
|
|
70
|
+
const parsed = Number.parseInt(value, 10);
|
|
71
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
72
|
+
throw new Error(`${fieldName} must be a positive integer`);
|
|
73
|
+
}
|
|
74
|
+
return parsed;
|
|
75
|
+
}
|
|
76
|
+
function parseNonNegativeInteger(value, fieldName) {
|
|
77
|
+
const parsed = Number.parseInt(value, 10);
|
|
78
|
+
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
79
|
+
throw new Error(`${fieldName} must be a non-negative integer`);
|
|
80
|
+
}
|
|
81
|
+
return parsed;
|
|
82
|
+
}
|
|
83
|
+
function parseOptionalNonNegativeInteger(args, name) {
|
|
84
|
+
const value = getOptionalOption(args, name);
|
|
85
|
+
return value === undefined ? undefined : parseNonNegativeInteger(value, `--${name}`);
|
|
86
|
+
}
|
|
87
|
+
function parseEnum(value, fieldName, allowed) {
|
|
88
|
+
if (allowed.includes(value)) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
throw new Error(`${fieldName} must be one of: ${allowed.join(", ")}`);
|
|
92
|
+
}
|
|
93
|
+
function now() {
|
|
94
|
+
return new Date().toISOString();
|
|
95
|
+
}
|
|
96
|
+
function sleep(ms) {
|
|
97
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
98
|
+
}
|
|
99
|
+
function isStateWithLatestEventId(value) {
|
|
100
|
+
return (typeof value === "object" &&
|
|
101
|
+
value !== null &&
|
|
102
|
+
typeof value.latestEventId === "string" &&
|
|
103
|
+
Array.isArray(value.eventIds));
|
|
104
|
+
}
|
|
105
|
+
function defaultObjectId(kind, seed) {
|
|
106
|
+
return `emporion:${kind}:${sha256Hex(seed)}`;
|
|
107
|
+
}
|
|
108
|
+
function toProtocolJsonObject(value) {
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
function toProtocolValue(value) {
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
function parsePaymentTerms(args, options) {
|
|
115
|
+
const amountOption = options?.amountOption ?? "amount-sats";
|
|
116
|
+
const currencyOption = options?.currencyOption ?? "currency";
|
|
117
|
+
const settlementOption = options?.settlementOption ?? "settlement";
|
|
118
|
+
return {
|
|
119
|
+
amountSats: parsePositiveInteger(requireOption(args, amountOption), `--${amountOption}`),
|
|
120
|
+
currency: parseEnum(getOptionalOption(args, currencyOption) ?? "SAT", `--${currencyOption}`, ["BTC", "SAT"]),
|
|
121
|
+
settlementMethod: parseEnum(getOptionalOption(args, settlementOption) ?? "lightning", `--${settlementOption}`, ["lightning", "custodial"])
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function mergePaymentTerms(args, current, options) {
|
|
125
|
+
const amountOption = options?.amountOption ?? "amount-sats";
|
|
126
|
+
const currencyOption = options?.currencyOption ?? "currency";
|
|
127
|
+
const settlementOption = options?.settlementOption ?? "settlement";
|
|
128
|
+
const amountValue = getOptionalOption(args, amountOption);
|
|
129
|
+
const currencyValue = getOptionalOption(args, currencyOption);
|
|
130
|
+
const settlementValue = getOptionalOption(args, settlementOption);
|
|
131
|
+
return {
|
|
132
|
+
amountSats: amountValue ? parsePositiveInteger(amountValue, `--${amountOption}`) : current.amountSats,
|
|
133
|
+
currency: currencyValue
|
|
134
|
+
? parseEnum(currencyValue, `--${currencyOption}`, ["BTC", "SAT"])
|
|
135
|
+
: current.currency,
|
|
136
|
+
settlementMethod: settlementValue
|
|
137
|
+
? parseEnum(settlementValue, `--${settlementOption}`, ["lightning", "custodial"])
|
|
138
|
+
: current.settlementMethod
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function parseLightningRefs(args) {
|
|
142
|
+
return getOptionValues(args, "lightning-ref")
|
|
143
|
+
.filter((value) => value !== "true")
|
|
144
|
+
.map((value) => {
|
|
145
|
+
const match = /^([^:]+):([^:]+):(.+)$/.exec(value);
|
|
146
|
+
if (!match) {
|
|
147
|
+
throw new Error("--lightning-ref must use <type>:<network>:<reference>");
|
|
148
|
+
}
|
|
149
|
+
const [, type, network, reference] = match;
|
|
150
|
+
if (!type || !network || !reference) {
|
|
151
|
+
throw new Error("--lightning-ref must use <type>:<network>:<reference>");
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
type: parseEnum(type, "--lightning-ref type", [
|
|
155
|
+
"bolt11",
|
|
156
|
+
"bolt12-offer",
|
|
157
|
+
"bolt12-invoice-request",
|
|
158
|
+
"custodial-payment-ref"
|
|
159
|
+
]),
|
|
160
|
+
network: parseEnum(network, "--lightning-ref network", [
|
|
161
|
+
"bitcoin",
|
|
162
|
+
"testnet",
|
|
163
|
+
"signet",
|
|
164
|
+
"regtest"
|
|
165
|
+
]),
|
|
166
|
+
reference
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function parseJsonOption(args, name) {
|
|
171
|
+
const value = requireOption(args, name);
|
|
172
|
+
try {
|
|
173
|
+
return JSON.parse(value);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
throw new Error(`--${name} must be valid JSON: ${error.message}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function getUniqueOptionValues(args, name) {
|
|
180
|
+
return [...new Set(getOptionValues(args, name).filter((value) => value !== "true"))].sort();
|
|
181
|
+
}
|
|
182
|
+
function writeJson(io, value) {
|
|
183
|
+
io.stdout(`${JSON.stringify(value, null, 2)}\n`);
|
|
184
|
+
}
|
|
185
|
+
async function withCliContext(dataDir, fn) {
|
|
186
|
+
const identityMaterial = await loadPersistentIdentityMaterial(dataDir);
|
|
187
|
+
const repository = await Protocol.ProtocolRepository.create(dataDir);
|
|
188
|
+
const transportStorage = await TransportStorage.create(dataDir, identityMaterial.storagePrimaryKey, createLogger("error"));
|
|
189
|
+
await transportStorage.initializeDefaults();
|
|
190
|
+
try {
|
|
191
|
+
return await fn({
|
|
192
|
+
dataDir,
|
|
193
|
+
identityMaterial,
|
|
194
|
+
repository,
|
|
195
|
+
transportStorage,
|
|
196
|
+
signer: {
|
|
197
|
+
did: identityMaterial.agentIdentity.did,
|
|
198
|
+
publicKey: identityMaterial.transportKeyPair.publicKey,
|
|
199
|
+
secretKey: identityMaterial.transportKeyPair.secretKey
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
await transportStorage.close();
|
|
205
|
+
await repository.close();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async function readRequiredState(repository, objectKind, objectId) {
|
|
209
|
+
const state = await repository.readObjectState(objectKind, objectId);
|
|
210
|
+
if (!state) {
|
|
211
|
+
throw new Error(`No ${objectKind} state found for ${objectId}`);
|
|
212
|
+
}
|
|
213
|
+
return state;
|
|
214
|
+
}
|
|
215
|
+
async function ensureAgentProfileExists(context) {
|
|
216
|
+
const profile = await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did);
|
|
217
|
+
if (profile) {
|
|
218
|
+
return profile;
|
|
219
|
+
}
|
|
220
|
+
const result = await appendEnvelope(context, {
|
|
221
|
+
objectKind: "agent-profile",
|
|
222
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
223
|
+
eventKind: "agent-profile.created",
|
|
224
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
225
|
+
payload: {}
|
|
226
|
+
});
|
|
227
|
+
return result.state;
|
|
228
|
+
}
|
|
229
|
+
function listActiveSpaceMemberDids(context, spaceId) {
|
|
230
|
+
const members = [];
|
|
231
|
+
for (const membership of context.repository.getSnapshot().spaceMemberships.values()) {
|
|
232
|
+
if (membership.spaceId === spaceId && membership.status !== "removed") {
|
|
233
|
+
members.push(membership.memberDid);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return [...new Set(members)].sort();
|
|
237
|
+
}
|
|
238
|
+
async function appendEnvelope(context, input) {
|
|
239
|
+
const currentState = await context.repository.readObjectState(input.objectKind, input.objectId);
|
|
240
|
+
const previousEventIds = isStateWithLatestEventId(currentState) ? [currentState.latestEventId] : [];
|
|
241
|
+
const unsignedEnvelope = Protocol.createUnsignedEnvelope({
|
|
242
|
+
objectKind: input.objectKind,
|
|
243
|
+
objectId: input.objectId,
|
|
244
|
+
eventKind: input.eventKind,
|
|
245
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
246
|
+
subjectId: input.subjectId,
|
|
247
|
+
issuedAt: input.issuedAt ?? now(),
|
|
248
|
+
previousEventIds,
|
|
249
|
+
payload: input.payload,
|
|
250
|
+
...(input.attachments ? { attachments: input.attachments } : {})
|
|
251
|
+
});
|
|
252
|
+
const envelope = Protocol.signProtocolEnvelope(unsignedEnvelope, context.signer);
|
|
253
|
+
await context.repository.appendEnvelope(envelope);
|
|
254
|
+
const nextState = await context.repository.readObjectState(input.objectKind, input.objectId);
|
|
255
|
+
if (nextState) {
|
|
256
|
+
const controlFeed = await context.transportStorage.openFeed("control");
|
|
257
|
+
const announcement = Protocol.createProtocolAnnouncement(envelope, nextState);
|
|
258
|
+
await controlFeed.append(Protocol.protocolAnnouncementToJson(announcement));
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
envelope,
|
|
262
|
+
state: nextState
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
async function handleAgentInit(args, io) {
|
|
266
|
+
const dataDir = requireOption(args, "data-dir");
|
|
267
|
+
await withCliContext(dataDir, async (context) => {
|
|
268
|
+
const displayName = getOptionalOption(args, "display-name");
|
|
269
|
+
const bio = getOptionalOption(args, "bio");
|
|
270
|
+
const currentProfile = await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did);
|
|
271
|
+
let mutation;
|
|
272
|
+
if (!currentProfile) {
|
|
273
|
+
mutation = await appendEnvelope(context, {
|
|
274
|
+
objectKind: "agent-profile",
|
|
275
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
276
|
+
eventKind: "agent-profile.created",
|
|
277
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
278
|
+
payload: {
|
|
279
|
+
...(displayName ? { displayName } : {}),
|
|
280
|
+
...(bio ? { bio } : {})
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
else if (displayName !== undefined || bio !== undefined) {
|
|
285
|
+
const profile = currentProfile;
|
|
286
|
+
if (displayName !== profile.displayName || bio !== profile.bio) {
|
|
287
|
+
mutation = await appendEnvelope(context, {
|
|
288
|
+
objectKind: "agent-profile",
|
|
289
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
290
|
+
eventKind: "agent-profile.updated",
|
|
291
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
292
|
+
payload: {
|
|
293
|
+
...(displayName !== undefined ? { displayName } : {}),
|
|
294
|
+
...(bio !== undefined ? { bio } : {})
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
writeJson(io, {
|
|
300
|
+
command: "agent.init",
|
|
301
|
+
identity: context.identityMaterial.agentIdentity,
|
|
302
|
+
profile: mutation?.state ??
|
|
303
|
+
(await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did)),
|
|
304
|
+
eventId: mutation?.envelope.eventId
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
async function handleAgentShow(args, io) {
|
|
309
|
+
const dataDir = requireOption(args, "data-dir");
|
|
310
|
+
await withCliContext(dataDir, async (context) => {
|
|
311
|
+
writeJson(io, {
|
|
312
|
+
command: "agent.show",
|
|
313
|
+
identity: context.identityMaterial.agentIdentity,
|
|
314
|
+
profile: await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did)
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
async function handleAgentPaymentEndpointAdd(args, io) {
|
|
319
|
+
const dataDir = requireOption(args, "data-dir");
|
|
320
|
+
await withCliContext(dataDir, async (context) => {
|
|
321
|
+
await ensureAgentProfileExists(context);
|
|
322
|
+
const capabilities = getCsvOptionValues(args, "capability");
|
|
323
|
+
if (capabilities.length === 0) {
|
|
324
|
+
throw new Error("At least one --capability is required");
|
|
325
|
+
}
|
|
326
|
+
const accountId = getOptionalOption(args, "account-id");
|
|
327
|
+
const nodeUri = getOptionalOption(args, "node-uri");
|
|
328
|
+
const bolt12Offer = getOptionalOption(args, "bolt12-offer");
|
|
329
|
+
const endpoint = {
|
|
330
|
+
id: requireOption(args, "id"),
|
|
331
|
+
network: parseEnum(getOptionalOption(args, "network") ?? "bitcoin", "--network", [
|
|
332
|
+
"bitcoin",
|
|
333
|
+
"testnet",
|
|
334
|
+
"signet",
|
|
335
|
+
"regtest"
|
|
336
|
+
]),
|
|
337
|
+
custodial: hasFlag(args, "custodial"),
|
|
338
|
+
capabilities,
|
|
339
|
+
...(accountId ? { accountId } : {}),
|
|
340
|
+
...(nodeUri ? { nodeUri } : {}),
|
|
341
|
+
...(bolt12Offer ? { bolt12Offer } : {})
|
|
342
|
+
};
|
|
343
|
+
const result = await appendEnvelope(context, {
|
|
344
|
+
objectKind: "agent-profile",
|
|
345
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
346
|
+
eventKind: "agent-profile.payment-endpoint-added",
|
|
347
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
348
|
+
payload: Protocol.paymentEndpointToJson(endpoint)
|
|
349
|
+
});
|
|
350
|
+
writeJson(io, {
|
|
351
|
+
command: "agent.payment-endpoint.add",
|
|
352
|
+
eventId: result.envelope.eventId,
|
|
353
|
+
profile: result.state
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
async function handleAgentPaymentEndpointRemove(args, io) {
|
|
358
|
+
const dataDir = requireOption(args, "data-dir");
|
|
359
|
+
const paymentEndpointId = requireOption(args, "payment-endpoint-id");
|
|
360
|
+
await withCliContext(dataDir, async (context) => {
|
|
361
|
+
await ensureAgentProfileExists(context);
|
|
362
|
+
const result = await appendEnvelope(context, {
|
|
363
|
+
objectKind: "agent-profile",
|
|
364
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
365
|
+
eventKind: "agent-profile.payment-endpoint-removed",
|
|
366
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
367
|
+
payload: {
|
|
368
|
+
paymentEndpointId
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
writeJson(io, {
|
|
372
|
+
command: "agent.payment-endpoint.remove",
|
|
373
|
+
eventId: result.envelope.eventId,
|
|
374
|
+
profile: result.state
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
async function handleAgentWalletAttestationAdd(args, io) {
|
|
379
|
+
const dataDir = requireOption(args, "data-dir");
|
|
380
|
+
await withCliContext(dataDir, async (context) => {
|
|
381
|
+
await ensureAgentProfileExists(context);
|
|
382
|
+
const attestedAt = getOptionalOption(args, "attested-at") ?? now();
|
|
383
|
+
const artifact = getOptionalOption(args, "artifact") ?? "";
|
|
384
|
+
const attestedCapacitySats = parseOptionalNonNegativeInteger(args, "capacity-sats");
|
|
385
|
+
const artifactUri = getOptionalOption(args, "artifact-uri");
|
|
386
|
+
const attestation = {
|
|
387
|
+
attestationId: requireOption(args, "attestation-id"),
|
|
388
|
+
issuerDid: getOptionalOption(args, "issuer-did") ?? context.identityMaterial.agentIdentity.did,
|
|
389
|
+
subjectDid: context.identityMaterial.agentIdentity.did,
|
|
390
|
+
walletAccountId: requireOption(args, "wallet-account-id"),
|
|
391
|
+
network: parseEnum(getOptionalOption(args, "network") ?? "bitcoin", "--network", [
|
|
392
|
+
"bitcoin",
|
|
393
|
+
"testnet",
|
|
394
|
+
"signet",
|
|
395
|
+
"regtest"
|
|
396
|
+
]),
|
|
397
|
+
currency: parseEnum(getOptionalOption(args, "currency") ?? "SAT", "--currency", ["BTC", "SAT"]),
|
|
398
|
+
attestedBalanceSats: parseNonNegativeInteger(requireOption(args, "balance-sats"), "--balance-sats"),
|
|
399
|
+
...(attestedCapacitySats !== undefined ? { attestedCapacitySats } : {}),
|
|
400
|
+
attestedAt,
|
|
401
|
+
expiresAt: requireOption(args, "expires-at"),
|
|
402
|
+
artifactHash: Protocol.createCredentialArtifactHash(artifact),
|
|
403
|
+
...(artifactUri ? { artifactUri } : {})
|
|
404
|
+
};
|
|
405
|
+
const result = await appendEnvelope(context, {
|
|
406
|
+
objectKind: "agent-profile",
|
|
407
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
408
|
+
eventKind: "agent-profile.wallet-attestation-added",
|
|
409
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
410
|
+
payload: Protocol.custodialWalletAttestationToJson(attestation)
|
|
411
|
+
});
|
|
412
|
+
writeJson(io, {
|
|
413
|
+
command: "agent.wallet-attestation.add",
|
|
414
|
+
eventId: result.envelope.eventId,
|
|
415
|
+
profile: result.state
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
async function handleAgentWalletAttestationRemove(args, io) {
|
|
420
|
+
const dataDir = requireOption(args, "data-dir");
|
|
421
|
+
const attestationId = requireOption(args, "attestation-id");
|
|
422
|
+
await withCliContext(dataDir, async (context) => {
|
|
423
|
+
await ensureAgentProfileExists(context);
|
|
424
|
+
const result = await appendEnvelope(context, {
|
|
425
|
+
objectKind: "agent-profile",
|
|
426
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
427
|
+
eventKind: "agent-profile.wallet-attestation-removed",
|
|
428
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
429
|
+
payload: {
|
|
430
|
+
attestationId
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
writeJson(io, {
|
|
434
|
+
command: "agent.wallet-attestation.remove",
|
|
435
|
+
eventId: result.envelope.eventId,
|
|
436
|
+
profile: result.state
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
async function handleAgentFeedbackAdd(args, io) {
|
|
441
|
+
const dataDir = requireOption(args, "data-dir");
|
|
442
|
+
await withCliContext(dataDir, async (context) => {
|
|
443
|
+
await ensureAgentProfileExists(context);
|
|
444
|
+
const issuedAt = getOptionalOption(args, "issued-at") ?? now();
|
|
445
|
+
const artifact = getOptionalOption(args, "artifact") ?? "";
|
|
446
|
+
const headline = getOptionalOption(args, "headline");
|
|
447
|
+
const comment = getOptionalOption(args, "comment");
|
|
448
|
+
const expiresAt = getOptionalOption(args, "expires-at");
|
|
449
|
+
const artifactUri = getOptionalOption(args, "artifact-uri");
|
|
450
|
+
const revocationRef = getOptionalOption(args, "revocation-ref");
|
|
451
|
+
const completionArtifactRef = getOptionalOption(args, "completion-artifact-ref");
|
|
452
|
+
const rulingRef = getOptionalOption(args, "ruling-ref");
|
|
453
|
+
const credential = {
|
|
454
|
+
credentialId: requireOption(args, "credential-id"),
|
|
455
|
+
issuerDid: requireOption(args, "issuer-did"),
|
|
456
|
+
subjectDid: context.identityMaterial.agentIdentity.did,
|
|
457
|
+
relatedContractId: requireOption(args, "contract-id"),
|
|
458
|
+
relatedAgreementId: requireOption(args, "agreement-id"),
|
|
459
|
+
...(completionArtifactRef ? { completionArtifactRef } : {}),
|
|
460
|
+
...(rulingRef ? { rulingRef } : {}),
|
|
461
|
+
summary: {
|
|
462
|
+
score: parseNonNegativeInteger(requireOption(args, "score"), "--score"),
|
|
463
|
+
maxScore: parsePositiveInteger(requireOption(args, "max-score"), "--max-score"),
|
|
464
|
+
...(headline ? { headline } : {}),
|
|
465
|
+
...(comment ? { comment } : {})
|
|
466
|
+
},
|
|
467
|
+
issuedAt,
|
|
468
|
+
...(expiresAt ? { expiresAt } : {}),
|
|
469
|
+
artifactHash: Protocol.createCredentialArtifactHash(artifact),
|
|
470
|
+
...(artifactUri ? { artifactUri } : {}),
|
|
471
|
+
...(revocationRef ? { revocationRef } : {})
|
|
472
|
+
};
|
|
473
|
+
const recorded = await appendEnvelope(context, {
|
|
474
|
+
objectKind: "feedback-credential-ref",
|
|
475
|
+
objectId: credential.credentialId,
|
|
476
|
+
eventKind: "feedback-credential-ref.recorded",
|
|
477
|
+
subjectId: credential.credentialId,
|
|
478
|
+
payload: Protocol.feedbackCredentialRefToJson(credential),
|
|
479
|
+
issuedAt
|
|
480
|
+
});
|
|
481
|
+
const added = await appendEnvelope(context, {
|
|
482
|
+
objectKind: "agent-profile",
|
|
483
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
484
|
+
eventKind: "agent-profile.feedback-credential-added",
|
|
485
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
486
|
+
payload: Protocol.feedbackCredentialRefToJson(credential)
|
|
487
|
+
});
|
|
488
|
+
writeJson(io, {
|
|
489
|
+
command: "agent.feedback.add",
|
|
490
|
+
feedbackEventId: recorded.envelope.eventId,
|
|
491
|
+
profileEventId: added.envelope.eventId,
|
|
492
|
+
profile: added.state,
|
|
493
|
+
feedback: await context.repository.readObjectState("feedback-credential-ref", credential.credentialId)
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
async function handleAgentFeedbackRemove(args, io) {
|
|
498
|
+
const dataDir = requireOption(args, "data-dir");
|
|
499
|
+
const credentialId = requireOption(args, "credential-id");
|
|
500
|
+
await withCliContext(dataDir, async (context) => {
|
|
501
|
+
await ensureAgentProfileExists(context);
|
|
502
|
+
const feedbackState = await context.repository.readObjectState("feedback-credential-ref", credentialId);
|
|
503
|
+
if (feedbackState) {
|
|
504
|
+
await appendEnvelope(context, {
|
|
505
|
+
objectKind: "feedback-credential-ref",
|
|
506
|
+
objectId: credentialId,
|
|
507
|
+
eventKind: "feedback-credential-ref.revoked",
|
|
508
|
+
subjectId: credentialId,
|
|
509
|
+
payload: {}
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
const removed = await appendEnvelope(context, {
|
|
513
|
+
objectKind: "agent-profile",
|
|
514
|
+
objectId: context.identityMaterial.agentIdentity.did,
|
|
515
|
+
eventKind: "agent-profile.feedback-credential-removed",
|
|
516
|
+
subjectId: context.identityMaterial.agentIdentity.did,
|
|
517
|
+
payload: {
|
|
518
|
+
credentialId
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
writeJson(io, {
|
|
522
|
+
command: "agent.feedback.remove",
|
|
523
|
+
profileEventId: removed.envelope.eventId,
|
|
524
|
+
profile: removed.state,
|
|
525
|
+
feedback: await context.repository.readObjectState("feedback-credential-ref", credentialId)
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
async function handleCompanyCreate(args, io) {
|
|
530
|
+
const dataDir = requireOption(args, "data-dir");
|
|
531
|
+
await withCliContext(dataDir, async (context) => {
|
|
532
|
+
const issuedAt = now();
|
|
533
|
+
const description = getOptionalOption(args, "description");
|
|
534
|
+
const payload = {
|
|
535
|
+
name: requireOption(args, "name"),
|
|
536
|
+
initialOwners: [context.identityMaterial.agentIdentity.did],
|
|
537
|
+
...(description ? { description } : {})
|
|
538
|
+
};
|
|
539
|
+
const companyDid = Protocol.deriveCompanyDidFromGenesis({
|
|
540
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
541
|
+
issuedAt,
|
|
542
|
+
payload
|
|
543
|
+
});
|
|
544
|
+
const result = await appendEnvelope(context, {
|
|
545
|
+
objectKind: "company",
|
|
546
|
+
objectId: companyDid,
|
|
547
|
+
eventKind: "company.genesis",
|
|
548
|
+
subjectId: companyDid,
|
|
549
|
+
payload: payload,
|
|
550
|
+
issuedAt
|
|
551
|
+
});
|
|
552
|
+
writeJson(io, {
|
|
553
|
+
command: "company.create",
|
|
554
|
+
companyDid,
|
|
555
|
+
eventId: result.envelope.eventId,
|
|
556
|
+
state: result.state
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
async function handleCompanyShow(args, io) {
|
|
561
|
+
const dataDir = requireOption(args, "data-dir");
|
|
562
|
+
const companyDid = requireOption(args, "company-did");
|
|
563
|
+
await withCliContext(dataDir, async (context) => {
|
|
564
|
+
writeJson(io, {
|
|
565
|
+
command: "company.show",
|
|
566
|
+
state: await context.repository.readObjectState("company", companyDid)
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
async function handleCompanyUpdate(args, io) {
|
|
571
|
+
const dataDir = requireOption(args, "data-dir");
|
|
572
|
+
const companyDid = requireOption(args, "company-did");
|
|
573
|
+
const name = getOptionalOption(args, "name");
|
|
574
|
+
const description = getOptionalOption(args, "description");
|
|
575
|
+
if (name === undefined && description === undefined) {
|
|
576
|
+
throw new Error("At least one of --name or --description is required");
|
|
577
|
+
}
|
|
578
|
+
await withCliContext(dataDir, async (context) => {
|
|
579
|
+
const result = await appendEnvelope(context, {
|
|
580
|
+
objectKind: "company",
|
|
581
|
+
objectId: companyDid,
|
|
582
|
+
eventKind: "company.profile-updated",
|
|
583
|
+
subjectId: companyDid,
|
|
584
|
+
payload: {
|
|
585
|
+
...(name !== undefined ? { name } : {}),
|
|
586
|
+
...(description !== undefined ? { description } : {})
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
writeJson(io, {
|
|
590
|
+
command: "company.update",
|
|
591
|
+
eventId: result.envelope.eventId,
|
|
592
|
+
state: result.state
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
async function handleCompanyRoleChange(args, io, mode) {
|
|
597
|
+
const dataDir = requireOption(args, "data-dir");
|
|
598
|
+
const companyDid = requireOption(args, "company-did");
|
|
599
|
+
await withCliContext(dataDir, async (context) => {
|
|
600
|
+
const result = await appendEnvelope(context, {
|
|
601
|
+
objectKind: "company",
|
|
602
|
+
objectId: companyDid,
|
|
603
|
+
eventKind: mode === "grant" ? "company.role-granted" : "company.role-revoked",
|
|
604
|
+
subjectId: companyDid,
|
|
605
|
+
payload: {
|
|
606
|
+
memberDid: requireOption(args, "member-did"),
|
|
607
|
+
role: parseEnum(requireOption(args, "role"), "--role", ["owner", "operator", "member"])
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
writeJson(io, {
|
|
611
|
+
command: mode === "grant" ? "company.grant-role" : "company.revoke-role",
|
|
612
|
+
eventId: result.envelope.eventId,
|
|
613
|
+
state: result.state
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
async function handleCompanyMarketMembership(args, io, mode) {
|
|
618
|
+
const dataDir = requireOption(args, "data-dir");
|
|
619
|
+
const companyDid = requireOption(args, "company-did");
|
|
620
|
+
const marketplaceId = requireOption(args, "marketplace");
|
|
621
|
+
await withCliContext(dataDir, async (context) => {
|
|
622
|
+
const result = await appendEnvelope(context, {
|
|
623
|
+
objectKind: "company",
|
|
624
|
+
objectId: companyDid,
|
|
625
|
+
eventKind: mode === "join" ? "company.market-joined" : "company.market-left",
|
|
626
|
+
subjectId: companyDid,
|
|
627
|
+
payload: {
|
|
628
|
+
marketplaceId
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
writeJson(io, {
|
|
632
|
+
command: mode === "join" ? "company.join-market" : "company.leave-market",
|
|
633
|
+
eventId: result.envelope.eventId,
|
|
634
|
+
state: result.state
|
|
635
|
+
});
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
async function handleCompanyTreasuryAttest(args, io) {
|
|
639
|
+
const dataDir = requireOption(args, "data-dir");
|
|
640
|
+
const companyDid = requireOption(args, "company-did");
|
|
641
|
+
const attestedAt = getOptionalOption(args, "attested-at") ?? now();
|
|
642
|
+
const artifact = getOptionalOption(args, "artifact") ?? "";
|
|
643
|
+
await withCliContext(dataDir, async (context) => {
|
|
644
|
+
const attestedCapacitySats = parseOptionalNonNegativeInteger(args, "capacity-sats");
|
|
645
|
+
const artifactUri = getOptionalOption(args, "artifact-uri");
|
|
646
|
+
const attestation = {
|
|
647
|
+
attestationId: requireOption(args, "attestation-id"),
|
|
648
|
+
issuerDid: getOptionalOption(args, "issuer-did") ?? context.identityMaterial.agentIdentity.did,
|
|
649
|
+
subjectDid: companyDid,
|
|
650
|
+
walletAccountId: requireOption(args, "wallet-account-id"),
|
|
651
|
+
network: parseEnum(getOptionalOption(args, "network") ?? "bitcoin", "--network", [
|
|
652
|
+
"bitcoin",
|
|
653
|
+
"testnet",
|
|
654
|
+
"signet",
|
|
655
|
+
"regtest"
|
|
656
|
+
]),
|
|
657
|
+
currency: parseEnum(getOptionalOption(args, "currency") ?? "SAT", "--currency", ["BTC", "SAT"]),
|
|
658
|
+
attestedBalanceSats: parseNonNegativeInteger(requireOption(args, "balance-sats"), "--balance-sats"),
|
|
659
|
+
...(attestedCapacitySats !== undefined ? { attestedCapacitySats } : {}),
|
|
660
|
+
attestedAt,
|
|
661
|
+
expiresAt: requireOption(args, "expires-at"),
|
|
662
|
+
artifactHash: Protocol.createCredentialArtifactHash(artifact),
|
|
663
|
+
...(artifactUri ? { artifactUri } : {})
|
|
664
|
+
};
|
|
665
|
+
const result = await appendEnvelope(context, {
|
|
666
|
+
objectKind: "company",
|
|
667
|
+
objectId: companyDid,
|
|
668
|
+
eventKind: "company.treasury-attested",
|
|
669
|
+
subjectId: companyDid,
|
|
670
|
+
payload: Protocol.custodialWalletAttestationToJson(attestation)
|
|
671
|
+
});
|
|
672
|
+
writeJson(io, {
|
|
673
|
+
command: "company.treasury-attest",
|
|
674
|
+
eventId: result.envelope.eventId,
|
|
675
|
+
state: result.state
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
async function handleCompanyTreasuryReserve(args, io) {
|
|
680
|
+
const dataDir = requireOption(args, "data-dir");
|
|
681
|
+
const companyDid = requireOption(args, "company-did");
|
|
682
|
+
const createdAt = getOptionalOption(args, "created-at") ?? now();
|
|
683
|
+
await withCliContext(dataDir, async (context) => {
|
|
684
|
+
const result = await appendEnvelope(context, {
|
|
685
|
+
objectKind: "company",
|
|
686
|
+
objectId: companyDid,
|
|
687
|
+
eventKind: "company.treasury-reserved",
|
|
688
|
+
subjectId: companyDid,
|
|
689
|
+
payload: {
|
|
690
|
+
reservationId: requireOption(args, "reservation-id"),
|
|
691
|
+
amountSats: parsePositiveInteger(requireOption(args, "amount-sats"), "--amount-sats"),
|
|
692
|
+
reason: requireOption(args, "reason"),
|
|
693
|
+
createdAt
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
writeJson(io, {
|
|
697
|
+
command: "company.treasury.reserve",
|
|
698
|
+
eventId: result.envelope.eventId,
|
|
699
|
+
state: result.state
|
|
700
|
+
});
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
async function handleCompanyTreasuryRelease(args, io) {
|
|
704
|
+
const dataDir = requireOption(args, "data-dir");
|
|
705
|
+
const companyDid = requireOption(args, "company-did");
|
|
706
|
+
await withCliContext(dataDir, async (context) => {
|
|
707
|
+
const result = await appendEnvelope(context, {
|
|
708
|
+
objectKind: "company",
|
|
709
|
+
objectId: companyDid,
|
|
710
|
+
eventKind: "company.treasury-released",
|
|
711
|
+
subjectId: companyDid,
|
|
712
|
+
payload: {
|
|
713
|
+
reservationId: requireOption(args, "reservation-id")
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
writeJson(io, {
|
|
717
|
+
command: "company.treasury.release",
|
|
718
|
+
eventId: result.envelope.eventId,
|
|
719
|
+
state: result.state
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
async function handleMarketProductCreate(args, io) {
|
|
724
|
+
const dataDir = requireOption(args, "data-dir");
|
|
725
|
+
await withCliContext(dataDir, async (context) => {
|
|
726
|
+
const issuedAt = now();
|
|
727
|
+
const description = getOptionalOption(args, "description");
|
|
728
|
+
const payload = {
|
|
729
|
+
marketplaceId: requireOption(args, "marketplace"),
|
|
730
|
+
ownerDid: getOptionalOption(args, "owner-did") ?? context.identityMaterial.agentIdentity.did,
|
|
731
|
+
title: requireOption(args, "title"),
|
|
732
|
+
...(description ? { description } : {})
|
|
733
|
+
};
|
|
734
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("product", toProtocolValue({
|
|
735
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
736
|
+
issuedAt,
|
|
737
|
+
payload: toProtocolJsonObject(payload)
|
|
738
|
+
}));
|
|
739
|
+
const result = await appendEnvelope(context, {
|
|
740
|
+
objectKind: "product",
|
|
741
|
+
objectId,
|
|
742
|
+
eventKind: "product.created",
|
|
743
|
+
subjectId: objectId,
|
|
744
|
+
payload: toProtocolJsonObject(payload),
|
|
745
|
+
issuedAt
|
|
746
|
+
});
|
|
747
|
+
writeJson(io, {
|
|
748
|
+
command: "market.product.create",
|
|
749
|
+
objectId,
|
|
750
|
+
eventId: result.envelope.eventId,
|
|
751
|
+
state: result.state
|
|
752
|
+
});
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
async function handleMarketProductUpdate(args, io) {
|
|
756
|
+
const dataDir = requireOption(args, "data-dir");
|
|
757
|
+
const objectId = requireOption(args, "id");
|
|
758
|
+
const title = getOptionalOption(args, "title");
|
|
759
|
+
const description = getOptionalOption(args, "description");
|
|
760
|
+
if (title === undefined && description === undefined) {
|
|
761
|
+
throw new Error("At least one of --title or --description is required");
|
|
762
|
+
}
|
|
763
|
+
await withCliContext(dataDir, async (context) => {
|
|
764
|
+
const result = await appendEnvelope(context, {
|
|
765
|
+
objectKind: "product",
|
|
766
|
+
objectId,
|
|
767
|
+
eventKind: "product.updated",
|
|
768
|
+
subjectId: objectId,
|
|
769
|
+
payload: toProtocolJsonObject({
|
|
770
|
+
...(title !== undefined ? { title } : {}),
|
|
771
|
+
...(description !== undefined ? { description } : {})
|
|
772
|
+
})
|
|
773
|
+
});
|
|
774
|
+
writeJson(io, {
|
|
775
|
+
command: "market.product.update",
|
|
776
|
+
objectId,
|
|
777
|
+
eventId: result.envelope.eventId,
|
|
778
|
+
state: result.state
|
|
779
|
+
});
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
async function handleMarketProductStateChange(args, io, eventKind) {
|
|
783
|
+
const dataDir = requireOption(args, "data-dir");
|
|
784
|
+
const objectId = requireOption(args, "id");
|
|
785
|
+
await withCliContext(dataDir, async (context) => {
|
|
786
|
+
const result = await appendEnvelope(context, {
|
|
787
|
+
objectKind: "product",
|
|
788
|
+
objectId,
|
|
789
|
+
eventKind,
|
|
790
|
+
subjectId: objectId,
|
|
791
|
+
payload: {}
|
|
792
|
+
});
|
|
793
|
+
writeJson(io, {
|
|
794
|
+
command: `market.product.${eventKind.split(".")[1]}`,
|
|
795
|
+
objectId,
|
|
796
|
+
eventId: result.envelope.eventId,
|
|
797
|
+
state: result.state
|
|
798
|
+
});
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
async function handleMarketListingPublish(args, io) {
|
|
802
|
+
const dataDir = requireOption(args, "data-dir");
|
|
803
|
+
await withCliContext(dataDir, async (context) => {
|
|
804
|
+
const issuedAt = now();
|
|
805
|
+
const productId = getOptionalOption(args, "product-id");
|
|
806
|
+
const payload = {
|
|
807
|
+
marketplaceId: requireOption(args, "marketplace"),
|
|
808
|
+
sellerDid: getOptionalOption(args, "seller-did") ?? context.identityMaterial.agentIdentity.did,
|
|
809
|
+
title: requireOption(args, "title"),
|
|
810
|
+
...(productId ? { productId } : {}),
|
|
811
|
+
paymentTerms: parsePaymentTerms(args)
|
|
812
|
+
};
|
|
813
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("listing", toProtocolValue({
|
|
814
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
815
|
+
issuedAt,
|
|
816
|
+
payload: toProtocolJsonObject(payload)
|
|
817
|
+
}));
|
|
818
|
+
const result = await appendEnvelope(context, {
|
|
819
|
+
objectKind: "listing",
|
|
820
|
+
objectId,
|
|
821
|
+
eventKind: "listing.published",
|
|
822
|
+
subjectId: objectId,
|
|
823
|
+
payload: toProtocolJsonObject(payload),
|
|
824
|
+
issuedAt
|
|
825
|
+
});
|
|
826
|
+
writeJson(io, {
|
|
827
|
+
command: "market.listing.publish",
|
|
828
|
+
objectId,
|
|
829
|
+
eventId: result.envelope.eventId,
|
|
830
|
+
state: result.state
|
|
831
|
+
});
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
async function handleMarketListingRevise(args, io) {
|
|
835
|
+
const dataDir = requireOption(args, "data-dir");
|
|
836
|
+
const objectId = requireOption(args, "id");
|
|
837
|
+
await withCliContext(dataDir, async (context) => {
|
|
838
|
+
const state = await readRequiredState(context.repository, "listing", objectId);
|
|
839
|
+
const title = getOptionalOption(args, "title");
|
|
840
|
+
const paymentTerms = mergePaymentTerms(args, state.paymentTerms);
|
|
841
|
+
const result = await appendEnvelope(context, {
|
|
842
|
+
objectKind: "listing",
|
|
843
|
+
objectId,
|
|
844
|
+
eventKind: "listing.revised",
|
|
845
|
+
subjectId: objectId,
|
|
846
|
+
payload: toProtocolJsonObject({
|
|
847
|
+
...(title !== undefined ? { title } : {}),
|
|
848
|
+
paymentTerms
|
|
849
|
+
})
|
|
850
|
+
});
|
|
851
|
+
writeJson(io, {
|
|
852
|
+
command: "market.listing.revise",
|
|
853
|
+
objectId,
|
|
854
|
+
eventId: result.envelope.eventId,
|
|
855
|
+
state: result.state
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
async function handleSimpleMarketStateChange(args, io, objectKind, eventKind) {
|
|
860
|
+
const dataDir = requireOption(args, "data-dir");
|
|
861
|
+
const objectId = requireOption(args, "id");
|
|
862
|
+
await withCliContext(dataDir, async (context) => {
|
|
863
|
+
const result = await appendEnvelope(context, {
|
|
864
|
+
objectKind,
|
|
865
|
+
objectId,
|
|
866
|
+
eventKind,
|
|
867
|
+
subjectId: objectId,
|
|
868
|
+
payload: {}
|
|
869
|
+
});
|
|
870
|
+
writeJson(io, {
|
|
871
|
+
command: `market.${objectKind}.${eventKind.split(".")[1]}`,
|
|
872
|
+
objectId,
|
|
873
|
+
eventId: result.envelope.eventId,
|
|
874
|
+
state: result.state
|
|
875
|
+
});
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
async function handleMarketRequestPublish(args, io) {
|
|
879
|
+
const dataDir = requireOption(args, "data-dir");
|
|
880
|
+
await withCliContext(dataDir, async (context) => {
|
|
881
|
+
const issuedAt = now();
|
|
882
|
+
const payload = {
|
|
883
|
+
marketplaceId: requireOption(args, "marketplace"),
|
|
884
|
+
requesterDid: getOptionalOption(args, "requester-did") ?? context.identityMaterial.agentIdentity.did,
|
|
885
|
+
title: requireOption(args, "title"),
|
|
886
|
+
paymentTerms: parsePaymentTerms(args)
|
|
887
|
+
};
|
|
888
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("request", toProtocolValue({
|
|
889
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
890
|
+
issuedAt,
|
|
891
|
+
payload: toProtocolJsonObject(payload)
|
|
892
|
+
}));
|
|
893
|
+
const result = await appendEnvelope(context, {
|
|
894
|
+
objectKind: "request",
|
|
895
|
+
objectId,
|
|
896
|
+
eventKind: "request.published",
|
|
897
|
+
subjectId: objectId,
|
|
898
|
+
payload: toProtocolJsonObject(payload),
|
|
899
|
+
issuedAt
|
|
900
|
+
});
|
|
901
|
+
writeJson(io, {
|
|
902
|
+
command: "market.request.publish",
|
|
903
|
+
objectId,
|
|
904
|
+
eventId: result.envelope.eventId,
|
|
905
|
+
state: result.state
|
|
906
|
+
});
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
async function handleMarketRequestRevise(args, io) {
|
|
910
|
+
const dataDir = requireOption(args, "data-dir");
|
|
911
|
+
const objectId = requireOption(args, "id");
|
|
912
|
+
await withCliContext(dataDir, async (context) => {
|
|
913
|
+
const state = await readRequiredState(context.repository, "request", objectId);
|
|
914
|
+
const title = getOptionalOption(args, "title");
|
|
915
|
+
const paymentTerms = mergePaymentTerms(args, state.paymentTerms);
|
|
916
|
+
const result = await appendEnvelope(context, {
|
|
917
|
+
objectKind: "request",
|
|
918
|
+
objectId,
|
|
919
|
+
eventKind: "request.revised",
|
|
920
|
+
subjectId: objectId,
|
|
921
|
+
payload: toProtocolJsonObject({
|
|
922
|
+
...(title !== undefined ? { title } : {}),
|
|
923
|
+
paymentTerms
|
|
924
|
+
})
|
|
925
|
+
});
|
|
926
|
+
writeJson(io, {
|
|
927
|
+
command: "market.request.revise",
|
|
928
|
+
objectId,
|
|
929
|
+
eventId: result.envelope.eventId,
|
|
930
|
+
state: result.state
|
|
931
|
+
});
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
async function handleMarketOfferSubmit(args, io) {
|
|
935
|
+
const dataDir = requireOption(args, "data-dir");
|
|
936
|
+
await withCliContext(dataDir, async (context) => {
|
|
937
|
+
const issuedAt = now();
|
|
938
|
+
const targetObjectId = getOptionalOption(args, "target-object-id");
|
|
939
|
+
const lightningRefs = parseLightningRefs(args);
|
|
940
|
+
const payload = {
|
|
941
|
+
marketplaceId: requireOption(args, "marketplace"),
|
|
942
|
+
proposerDid: getOptionalOption(args, "proposer-did") ?? context.identityMaterial.agentIdentity.did,
|
|
943
|
+
...(targetObjectId ? { targetObjectId } : {}),
|
|
944
|
+
paymentTerms: parsePaymentTerms(args),
|
|
945
|
+
...(lightningRefs.length > 0 ? { lightningRefs } : {})
|
|
946
|
+
};
|
|
947
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("offer", toProtocolValue({
|
|
948
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
949
|
+
issuedAt,
|
|
950
|
+
payload: toProtocolJsonObject(payload)
|
|
951
|
+
}));
|
|
952
|
+
const result = await appendEnvelope(context, {
|
|
953
|
+
objectKind: "offer",
|
|
954
|
+
objectId,
|
|
955
|
+
eventKind: "offer.submitted",
|
|
956
|
+
subjectId: objectId,
|
|
957
|
+
payload: toProtocolJsonObject(payload),
|
|
958
|
+
issuedAt
|
|
959
|
+
});
|
|
960
|
+
writeJson(io, {
|
|
961
|
+
command: "market.offer.submit",
|
|
962
|
+
objectId,
|
|
963
|
+
eventId: result.envelope.eventId,
|
|
964
|
+
state: result.state
|
|
965
|
+
});
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
async function handleMarketOfferCounter(args, io) {
|
|
969
|
+
const dataDir = requireOption(args, "data-dir");
|
|
970
|
+
const objectId = requireOption(args, "id");
|
|
971
|
+
await withCliContext(dataDir, async (context) => {
|
|
972
|
+
const state = await readRequiredState(context.repository, "offer", objectId);
|
|
973
|
+
const lightningRefs = parseLightningRefs(args);
|
|
974
|
+
const result = await appendEnvelope(context, {
|
|
975
|
+
objectKind: "offer",
|
|
976
|
+
objectId,
|
|
977
|
+
eventKind: "offer.countered",
|
|
978
|
+
subjectId: objectId,
|
|
979
|
+
payload: toProtocolJsonObject({
|
|
980
|
+
paymentTerms: mergePaymentTerms(args, state.paymentTerms),
|
|
981
|
+
...(lightningRefs.length > 0 ? { lightningRefs } : {})
|
|
982
|
+
})
|
|
983
|
+
});
|
|
984
|
+
writeJson(io, {
|
|
985
|
+
command: "market.offer.counter",
|
|
986
|
+
objectId,
|
|
987
|
+
eventId: result.envelope.eventId,
|
|
988
|
+
state: result.state
|
|
989
|
+
});
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
async function handleMarketBidSubmit(args, io) {
|
|
993
|
+
const dataDir = requireOption(args, "data-dir");
|
|
994
|
+
await withCliContext(dataDir, async (context) => {
|
|
995
|
+
const issuedAt = now();
|
|
996
|
+
const targetObjectId = getOptionalOption(args, "target-object-id");
|
|
997
|
+
const lightningRefs = parseLightningRefs(args);
|
|
998
|
+
const payload = {
|
|
999
|
+
marketplaceId: requireOption(args, "marketplace"),
|
|
1000
|
+
proposerDid: getOptionalOption(args, "proposer-did") ?? context.identityMaterial.agentIdentity.did,
|
|
1001
|
+
...(targetObjectId ? { targetObjectId } : {}),
|
|
1002
|
+
paymentTerms: parsePaymentTerms(args),
|
|
1003
|
+
...(lightningRefs.length > 0 ? { lightningRefs } : {})
|
|
1004
|
+
};
|
|
1005
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("bid", toProtocolValue({
|
|
1006
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1007
|
+
issuedAt,
|
|
1008
|
+
payload: toProtocolJsonObject(payload)
|
|
1009
|
+
}));
|
|
1010
|
+
const result = await appendEnvelope(context, {
|
|
1011
|
+
objectKind: "bid",
|
|
1012
|
+
objectId,
|
|
1013
|
+
eventKind: "bid.submitted",
|
|
1014
|
+
subjectId: objectId,
|
|
1015
|
+
payload: toProtocolJsonObject(payload),
|
|
1016
|
+
issuedAt
|
|
1017
|
+
});
|
|
1018
|
+
writeJson(io, {
|
|
1019
|
+
command: "market.bid.submit",
|
|
1020
|
+
objectId,
|
|
1021
|
+
eventId: result.envelope.eventId,
|
|
1022
|
+
state: result.state
|
|
1023
|
+
});
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
async function handleMarketBidCounter(args, io) {
|
|
1027
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1028
|
+
const objectId = requireOption(args, "id");
|
|
1029
|
+
await withCliContext(dataDir, async (context) => {
|
|
1030
|
+
const state = await readRequiredState(context.repository, "bid", objectId);
|
|
1031
|
+
const lightningRefs = parseLightningRefs(args);
|
|
1032
|
+
const result = await appendEnvelope(context, {
|
|
1033
|
+
objectKind: "bid",
|
|
1034
|
+
objectId,
|
|
1035
|
+
eventKind: "bid.countered",
|
|
1036
|
+
subjectId: objectId,
|
|
1037
|
+
payload: toProtocolJsonObject({
|
|
1038
|
+
paymentTerms: mergePaymentTerms(args, state.paymentTerms),
|
|
1039
|
+
...(lightningRefs.length > 0 ? { lightningRefs } : {})
|
|
1040
|
+
})
|
|
1041
|
+
});
|
|
1042
|
+
writeJson(io, {
|
|
1043
|
+
command: "market.bid.counter",
|
|
1044
|
+
objectId,
|
|
1045
|
+
eventId: result.envelope.eventId,
|
|
1046
|
+
state: result.state
|
|
1047
|
+
});
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
function deriveAgreementCounterparties(sourceKind, sourceState, actorDid, explicitCounterparties) {
|
|
1051
|
+
if (explicitCounterparties.length > 0) {
|
|
1052
|
+
return [...new Set(explicitCounterparties)].sort();
|
|
1053
|
+
}
|
|
1054
|
+
switch (sourceKind) {
|
|
1055
|
+
case "offer":
|
|
1056
|
+
return [...new Set([sourceState.proposerDid, actorDid])].sort();
|
|
1057
|
+
case "bid":
|
|
1058
|
+
return [...new Set([sourceState.proposerDid, actorDid])].sort();
|
|
1059
|
+
case "listing":
|
|
1060
|
+
return [...new Set([sourceState.sellerDid, actorDid])].sort();
|
|
1061
|
+
case "request":
|
|
1062
|
+
return [...new Set([sourceState.requesterDid, actorDid])].sort();
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
async function handleMarketAgreementCreate(args, io) {
|
|
1066
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1067
|
+
const sourceKind = parseEnum(requireOption(args, "source-kind"), "--source-kind", [
|
|
1068
|
+
"offer",
|
|
1069
|
+
"bid",
|
|
1070
|
+
"listing",
|
|
1071
|
+
"request"
|
|
1072
|
+
]);
|
|
1073
|
+
const sourceObjectId = requireOption(args, "source-id");
|
|
1074
|
+
await withCliContext(dataDir, async (context) => {
|
|
1075
|
+
const issuedAt = now();
|
|
1076
|
+
const sourceState = await readRequiredState(context.repository, sourceKind, sourceObjectId);
|
|
1077
|
+
const marketplaceId = getOptionalOption(args, "marketplace") ?? sourceState.marketplaceId;
|
|
1078
|
+
const paymentTerms = getOptionalOption(args, "amount-sats") || getOptionalOption(args, "currency") || getOptionalOption(args, "settlement")
|
|
1079
|
+
? mergePaymentTerms(args, sourceState.paymentTerms)
|
|
1080
|
+
: sourceState.paymentTerms;
|
|
1081
|
+
const deliverables = getCsvOptionValues(args, "deliverable");
|
|
1082
|
+
if (deliverables.length === 0) {
|
|
1083
|
+
throw new Error("At least one --deliverable is required");
|
|
1084
|
+
}
|
|
1085
|
+
const counterparties = deriveAgreementCounterparties(sourceKind, sourceState, context.identityMaterial.agentIdentity.did, getCsvOptionValues(args, "counterparty"));
|
|
1086
|
+
const lightningRefs = parseLightningRefs(args);
|
|
1087
|
+
const payload = {
|
|
1088
|
+
marketplaceId,
|
|
1089
|
+
sourceObjectKind: sourceKind,
|
|
1090
|
+
sourceObjectId,
|
|
1091
|
+
counterparties,
|
|
1092
|
+
deliverables,
|
|
1093
|
+
paymentTerms,
|
|
1094
|
+
...(lightningRefs.length > 0 ? { lightningRefs } : {})
|
|
1095
|
+
};
|
|
1096
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("agreement", toProtocolValue({
|
|
1097
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1098
|
+
issuedAt,
|
|
1099
|
+
payload: toProtocolJsonObject(payload)
|
|
1100
|
+
}));
|
|
1101
|
+
const result = await appendEnvelope(context, {
|
|
1102
|
+
objectKind: "agreement",
|
|
1103
|
+
objectId,
|
|
1104
|
+
eventKind: "agreement.created",
|
|
1105
|
+
subjectId: objectId,
|
|
1106
|
+
payload: toProtocolJsonObject(payload),
|
|
1107
|
+
issuedAt
|
|
1108
|
+
});
|
|
1109
|
+
writeJson(io, {
|
|
1110
|
+
command: "market.agreement.create",
|
|
1111
|
+
objectId,
|
|
1112
|
+
eventId: result.envelope.eventId,
|
|
1113
|
+
state: result.state
|
|
1114
|
+
});
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
async function handleContractCreate(args, io) {
|
|
1118
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1119
|
+
await withCliContext(dataDir, async (context) => {
|
|
1120
|
+
const issuedAt = now();
|
|
1121
|
+
const sponsorDid = getOptionalOption(args, "sponsor-did");
|
|
1122
|
+
const companyDid = getOptionalOption(args, "company-did");
|
|
1123
|
+
const payload = {
|
|
1124
|
+
originRef: {
|
|
1125
|
+
objectKind: parseEnum(requireOption(args, "origin-kind"), "--origin-kind", [
|
|
1126
|
+
"agreement",
|
|
1127
|
+
"listing",
|
|
1128
|
+
"request",
|
|
1129
|
+
"offer",
|
|
1130
|
+
"bid"
|
|
1131
|
+
]),
|
|
1132
|
+
objectId: requireOption(args, "origin-id")
|
|
1133
|
+
},
|
|
1134
|
+
parties: getCsvOptionValues(args, "party"),
|
|
1135
|
+
...(sponsorDid ? { sponsorDid } : {}),
|
|
1136
|
+
...(companyDid ? { companyDid } : {}),
|
|
1137
|
+
scope: requireOption(args, "scope"),
|
|
1138
|
+
milestones: parseJsonOption(args, "milestones-json"),
|
|
1139
|
+
deliverableSchema: parseJsonOption(args, "deliverable-schema-json"),
|
|
1140
|
+
proofPolicy: parseJsonOption(args, "proof-policy-json"),
|
|
1141
|
+
resolutionPolicy: parseJsonOption(args, "resolution-policy-json"),
|
|
1142
|
+
settlementPolicy: parseJsonOption(args, "settlement-policy-json"),
|
|
1143
|
+
deadlinePolicy: parseJsonOption(args, "deadline-policy-json")
|
|
1144
|
+
};
|
|
1145
|
+
if (payload.parties.length === 0) {
|
|
1146
|
+
throw new Error("At least one --party is required");
|
|
1147
|
+
}
|
|
1148
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("contract", toProtocolValue({
|
|
1149
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1150
|
+
issuedAt,
|
|
1151
|
+
payload: toProtocolJsonObject(payload)
|
|
1152
|
+
}));
|
|
1153
|
+
const result = await appendEnvelope(context, {
|
|
1154
|
+
objectKind: "contract",
|
|
1155
|
+
objectId,
|
|
1156
|
+
eventKind: "contract.created",
|
|
1157
|
+
subjectId: objectId,
|
|
1158
|
+
payload: Protocol.contractCreatedPayloadToJson(payload),
|
|
1159
|
+
issuedAt
|
|
1160
|
+
});
|
|
1161
|
+
writeJson(io, {
|
|
1162
|
+
command: "contract.create",
|
|
1163
|
+
objectId,
|
|
1164
|
+
eventId: result.envelope.eventId,
|
|
1165
|
+
state: result.state
|
|
1166
|
+
});
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
async function handleContractMilestoneAction(args, io, eventKind) {
|
|
1170
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1171
|
+
const contractId = requireOption(args, "id");
|
|
1172
|
+
const milestoneId = requireOption(args, "milestone-id");
|
|
1173
|
+
await withCliContext(dataDir, async (context) => {
|
|
1174
|
+
const payload = eventKind === "contract.milestone-opened"
|
|
1175
|
+
? { milestoneId }
|
|
1176
|
+
: eventKind === "contract.milestone-rejected"
|
|
1177
|
+
? { milestoneId, reason: requireOption(args, "reason") }
|
|
1178
|
+
: {
|
|
1179
|
+
milestoneId,
|
|
1180
|
+
...(getUniqueOptionValues(args, "evidence-bundle-id").length > 0
|
|
1181
|
+
? { evidenceBundleIds: getUniqueOptionValues(args, "evidence-bundle-id") }
|
|
1182
|
+
: {}),
|
|
1183
|
+
...(getUniqueOptionValues(args, "oracle-attestation-id").length > 0
|
|
1184
|
+
? { oracleAttestationIds: getUniqueOptionValues(args, "oracle-attestation-id") }
|
|
1185
|
+
: {})
|
|
1186
|
+
};
|
|
1187
|
+
const result = await appendEnvelope(context, {
|
|
1188
|
+
objectKind: "contract",
|
|
1189
|
+
objectId: contractId,
|
|
1190
|
+
eventKind,
|
|
1191
|
+
subjectId: contractId,
|
|
1192
|
+
payload: toProtocolJsonObject(payload)
|
|
1193
|
+
});
|
|
1194
|
+
writeJson(io, {
|
|
1195
|
+
command: `contract.${eventKind.split(".")[1]}`,
|
|
1196
|
+
objectId: contractId,
|
|
1197
|
+
eventId: result.envelope.eventId,
|
|
1198
|
+
state: result.state
|
|
1199
|
+
});
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
async function handleContractStateChange(args, io, eventKind) {
|
|
1203
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1204
|
+
const contractId = requireOption(args, "id");
|
|
1205
|
+
await withCliContext(dataDir, async (context) => {
|
|
1206
|
+
const result = await appendEnvelope(context, {
|
|
1207
|
+
objectKind: "contract",
|
|
1208
|
+
objectId: contractId,
|
|
1209
|
+
eventKind,
|
|
1210
|
+
subjectId: contractId,
|
|
1211
|
+
payload: {}
|
|
1212
|
+
});
|
|
1213
|
+
writeJson(io, {
|
|
1214
|
+
command: `contract.${eventKind.split(".")[1]}`,
|
|
1215
|
+
objectId: contractId,
|
|
1216
|
+
eventId: result.envelope.eventId,
|
|
1217
|
+
state: result.state
|
|
1218
|
+
});
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
async function handleEvidenceRecord(args, io) {
|
|
1222
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1223
|
+
await withCliContext(dataDir, async (context) => {
|
|
1224
|
+
const issuedAt = now();
|
|
1225
|
+
const artifactRefs = getOptionalOption(args, "artifact-json")
|
|
1226
|
+
? parseJsonOption(args, "artifact-json")
|
|
1227
|
+
: [];
|
|
1228
|
+
const verifierRefs = getOptionalOption(args, "verifier-json")
|
|
1229
|
+
? parseJsonOption(args, "verifier-json")
|
|
1230
|
+
: [];
|
|
1231
|
+
const reproInstructions = getOptionalOption(args, "repro");
|
|
1232
|
+
const executionTranscriptRefs = getUniqueOptionValues(args, "execution-transcript-ref");
|
|
1233
|
+
const hashes = Object.fromEntries(getUniqueOptionValues(args, "hash").map((entry) => {
|
|
1234
|
+
const [name, hash] = entry.split("=", 2);
|
|
1235
|
+
if (!name || !hash) {
|
|
1236
|
+
throw new Error("--hash must use <name>=<hex-hash>");
|
|
1237
|
+
}
|
|
1238
|
+
return [name, hash];
|
|
1239
|
+
}));
|
|
1240
|
+
const payload = {
|
|
1241
|
+
contractId: requireOption(args, "contract-id"),
|
|
1242
|
+
milestoneId: requireOption(args, "milestone-id"),
|
|
1243
|
+
submitterDid: context.identityMaterial.agentIdentity.did,
|
|
1244
|
+
artifactRefs,
|
|
1245
|
+
verifierRefs,
|
|
1246
|
+
proofModes: getCsvOptionValues(args, "proof-mode"),
|
|
1247
|
+
...(reproInstructions ? { reproInstructions } : {}),
|
|
1248
|
+
hashes,
|
|
1249
|
+
executionTranscriptRefs
|
|
1250
|
+
};
|
|
1251
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("evidence-bundle", toProtocolValue({
|
|
1252
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1253
|
+
issuedAt,
|
|
1254
|
+
payload: toProtocolJsonObject(payload)
|
|
1255
|
+
}));
|
|
1256
|
+
const result = await appendEnvelope(context, {
|
|
1257
|
+
objectKind: "evidence-bundle",
|
|
1258
|
+
objectId,
|
|
1259
|
+
eventKind: "evidence-bundle.recorded",
|
|
1260
|
+
subjectId: objectId,
|
|
1261
|
+
payload: Protocol.evidenceBundlePayloadToJson(payload),
|
|
1262
|
+
issuedAt
|
|
1263
|
+
});
|
|
1264
|
+
writeJson(io, {
|
|
1265
|
+
command: "evidence.record",
|
|
1266
|
+
objectId,
|
|
1267
|
+
eventId: result.envelope.eventId,
|
|
1268
|
+
state: result.state
|
|
1269
|
+
});
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
async function handleOracleAttest(args, io) {
|
|
1273
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1274
|
+
await withCliContext(dataDir, async (context) => {
|
|
1275
|
+
const issuedAt = getOptionalOption(args, "issued-at") ?? now();
|
|
1276
|
+
const milestoneId = getOptionalOption(args, "milestone-id");
|
|
1277
|
+
const payload = {
|
|
1278
|
+
oracleDid: context.identityMaterial.agentIdentity.did,
|
|
1279
|
+
claimType: requireOption(args, "claim-type"),
|
|
1280
|
+
subjectRef: {
|
|
1281
|
+
objectKind: parseEnum(requireOption(args, "subject-kind"), "--subject-kind", [
|
|
1282
|
+
"contract",
|
|
1283
|
+
"evidence-bundle",
|
|
1284
|
+
"dispute-case"
|
|
1285
|
+
]),
|
|
1286
|
+
objectId: requireOption(args, "subject-id"),
|
|
1287
|
+
...(milestoneId ? { milestoneId } : {})
|
|
1288
|
+
},
|
|
1289
|
+
outcome: parseEnum(requireOption(args, "outcome"), "--outcome", [
|
|
1290
|
+
"satisfied",
|
|
1291
|
+
"unsatisfied",
|
|
1292
|
+
"accepted",
|
|
1293
|
+
"rejected",
|
|
1294
|
+
"completed",
|
|
1295
|
+
"breached"
|
|
1296
|
+
]),
|
|
1297
|
+
evidenceRefs: getUniqueOptionValues(args, "evidence-ref"),
|
|
1298
|
+
issuedAt,
|
|
1299
|
+
expiresAt: requireOption(args, "expires-at")
|
|
1300
|
+
};
|
|
1301
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("oracle-attestation", toProtocolValue({
|
|
1302
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1303
|
+
issuedAt,
|
|
1304
|
+
payload: toProtocolJsonObject(payload)
|
|
1305
|
+
}));
|
|
1306
|
+
const result = await appendEnvelope(context, {
|
|
1307
|
+
objectKind: "oracle-attestation",
|
|
1308
|
+
objectId,
|
|
1309
|
+
eventKind: "oracle-attestation.recorded",
|
|
1310
|
+
subjectId: objectId,
|
|
1311
|
+
payload: Protocol.oracleAttestationPayloadToJson(payload),
|
|
1312
|
+
issuedAt
|
|
1313
|
+
});
|
|
1314
|
+
writeJson(io, {
|
|
1315
|
+
command: "oracle.attest",
|
|
1316
|
+
objectId,
|
|
1317
|
+
eventId: result.envelope.eventId,
|
|
1318
|
+
state: result.state
|
|
1319
|
+
});
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
async function handleDisputeOpen(args, io) {
|
|
1323
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1324
|
+
await withCliContext(dataDir, async (context) => {
|
|
1325
|
+
const issuedAt = now();
|
|
1326
|
+
const payload = {
|
|
1327
|
+
contractId: requireOption(args, "contract-id"),
|
|
1328
|
+
...(getOptionalOption(args, "milestone-id") ? { milestoneId: getOptionalOption(args, "milestone-id") } : {}),
|
|
1329
|
+
reason: requireOption(args, "reason")
|
|
1330
|
+
};
|
|
1331
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("dispute-case", toProtocolValue({
|
|
1332
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1333
|
+
issuedAt,
|
|
1334
|
+
payload: toProtocolJsonObject(payload)
|
|
1335
|
+
}));
|
|
1336
|
+
const result = await appendEnvelope(context, {
|
|
1337
|
+
objectKind: "dispute-case",
|
|
1338
|
+
objectId,
|
|
1339
|
+
eventKind: "dispute.opened",
|
|
1340
|
+
subjectId: objectId,
|
|
1341
|
+
payload: toProtocolJsonObject(payload),
|
|
1342
|
+
issuedAt
|
|
1343
|
+
});
|
|
1344
|
+
writeJson(io, {
|
|
1345
|
+
command: "dispute.open",
|
|
1346
|
+
objectId,
|
|
1347
|
+
eventId: result.envelope.eventId,
|
|
1348
|
+
state: result.state
|
|
1349
|
+
});
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
async function handleDisputeAddEvidence(args, io) {
|
|
1353
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1354
|
+
const objectId = requireOption(args, "id");
|
|
1355
|
+
await withCliContext(dataDir, async (context) => {
|
|
1356
|
+
const evidenceBundleIds = getUniqueOptionValues(args, "evidence-bundle-id");
|
|
1357
|
+
if (evidenceBundleIds.length === 0) {
|
|
1358
|
+
throw new Error("At least one --evidence-bundle-id is required");
|
|
1359
|
+
}
|
|
1360
|
+
const result = await appendEnvelope(context, {
|
|
1361
|
+
objectKind: "dispute-case",
|
|
1362
|
+
objectId,
|
|
1363
|
+
eventKind: "dispute.evidence-added",
|
|
1364
|
+
subjectId: objectId,
|
|
1365
|
+
payload: {
|
|
1366
|
+
evidenceBundleIds
|
|
1367
|
+
}
|
|
1368
|
+
});
|
|
1369
|
+
writeJson(io, {
|
|
1370
|
+
command: "dispute.add-evidence",
|
|
1371
|
+
objectId,
|
|
1372
|
+
eventId: result.envelope.eventId,
|
|
1373
|
+
state: result.state
|
|
1374
|
+
});
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
async function handleDisputeRequestOracle(args, io) {
|
|
1378
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1379
|
+
const objectId = requireOption(args, "id");
|
|
1380
|
+
await withCliContext(dataDir, async (context) => {
|
|
1381
|
+
const result = await appendEnvelope(context, {
|
|
1382
|
+
objectKind: "dispute-case",
|
|
1383
|
+
objectId,
|
|
1384
|
+
eventKind: "dispute.oracle-requested",
|
|
1385
|
+
subjectId: objectId,
|
|
1386
|
+
payload: {}
|
|
1387
|
+
});
|
|
1388
|
+
writeJson(io, {
|
|
1389
|
+
command: "dispute.request-oracle",
|
|
1390
|
+
objectId,
|
|
1391
|
+
eventId: result.envelope.eventId,
|
|
1392
|
+
state: result.state
|
|
1393
|
+
});
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
async function handleDisputeRule(args, io) {
|
|
1397
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1398
|
+
const objectId = requireOption(args, "id");
|
|
1399
|
+
await withCliContext(dataDir, async (context) => {
|
|
1400
|
+
const deterministicVerifierId = getOptionalOption(args, "deterministic-verifier-id");
|
|
1401
|
+
const summary = getOptionalOption(args, "summary");
|
|
1402
|
+
const ruling = {
|
|
1403
|
+
outcome: parseEnum(requireOption(args, "outcome"), "--outcome", [
|
|
1404
|
+
"fulfilled",
|
|
1405
|
+
"breach",
|
|
1406
|
+
"refund",
|
|
1407
|
+
"partial",
|
|
1408
|
+
"rejected-claim"
|
|
1409
|
+
]),
|
|
1410
|
+
resolutionMode: parseEnum(requireOption(args, "resolution-mode"), "--resolution-mode", [
|
|
1411
|
+
"deterministic",
|
|
1412
|
+
"oracle",
|
|
1413
|
+
"mutual",
|
|
1414
|
+
"hybrid"
|
|
1415
|
+
]),
|
|
1416
|
+
...(deterministicVerifierId ? { deterministicVerifierId } : {}),
|
|
1417
|
+
oracleAttestationIds: getUniqueOptionValues(args, "oracle-attestation-id"),
|
|
1418
|
+
evidenceBundleIds: getUniqueOptionValues(args, "evidence-bundle-id"),
|
|
1419
|
+
approverDids: getCsvOptionValues(args, "approver"),
|
|
1420
|
+
...(summary ? { summary } : {})
|
|
1421
|
+
};
|
|
1422
|
+
const result = await appendEnvelope(context, {
|
|
1423
|
+
objectKind: "dispute-case",
|
|
1424
|
+
objectId,
|
|
1425
|
+
eventKind: "dispute.ruled",
|
|
1426
|
+
subjectId: objectId,
|
|
1427
|
+
payload: Protocol.disputeRulingToJson(ruling)
|
|
1428
|
+
});
|
|
1429
|
+
writeJson(io, {
|
|
1430
|
+
command: "dispute.rule",
|
|
1431
|
+
objectId,
|
|
1432
|
+
eventId: result.envelope.eventId,
|
|
1433
|
+
state: result.state
|
|
1434
|
+
});
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
async function handleDisputeClose(args, io) {
|
|
1438
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1439
|
+
const objectId = requireOption(args, "id");
|
|
1440
|
+
await withCliContext(dataDir, async (context) => {
|
|
1441
|
+
const result = await appendEnvelope(context, {
|
|
1442
|
+
objectKind: "dispute-case",
|
|
1443
|
+
objectId,
|
|
1444
|
+
eventKind: "dispute.closed",
|
|
1445
|
+
subjectId: objectId,
|
|
1446
|
+
payload: {}
|
|
1447
|
+
});
|
|
1448
|
+
writeJson(io, {
|
|
1449
|
+
command: "dispute.close",
|
|
1450
|
+
objectId,
|
|
1451
|
+
eventId: result.envelope.eventId,
|
|
1452
|
+
state: result.state
|
|
1453
|
+
});
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
async function handleSpaceCreate(args, io) {
|
|
1457
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1458
|
+
await withCliContext(dataDir, async (context) => {
|
|
1459
|
+
const issuedAt = now();
|
|
1460
|
+
const spaceId = getOptionalOption(args, "id") ?? defaultObjectId("space", toProtocolValue({
|
|
1461
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1462
|
+
issuedAt,
|
|
1463
|
+
ownerRef: {
|
|
1464
|
+
kind: requireOption(args, "owner-kind"),
|
|
1465
|
+
id: requireOption(args, "owner-id")
|
|
1466
|
+
}
|
|
1467
|
+
}));
|
|
1468
|
+
const membershipPolicy = getOptionalOption(args, "membership-policy-json")
|
|
1469
|
+
? parseJsonOption(args, "membership-policy-json")
|
|
1470
|
+
: {
|
|
1471
|
+
mode: "invite-only",
|
|
1472
|
+
ownerMemberDids: [context.identityMaterial.agentIdentity.did]
|
|
1473
|
+
};
|
|
1474
|
+
const encryptionPolicy = getOptionalOption(args, "encryption-policy-json")
|
|
1475
|
+
? parseJsonOption(args, "encryption-policy-json")
|
|
1476
|
+
: {
|
|
1477
|
+
mode: "member-sealed-box",
|
|
1478
|
+
keyAgreementMethod: "did-keyagreement-v1"
|
|
1479
|
+
};
|
|
1480
|
+
const payload = {
|
|
1481
|
+
spaceKind: parseEnum(requireOption(args, "space-kind"), "--space-kind", [
|
|
1482
|
+
"direct-inbox",
|
|
1483
|
+
"contract-thread",
|
|
1484
|
+
"company-room",
|
|
1485
|
+
"market-room"
|
|
1486
|
+
]),
|
|
1487
|
+
ownerRef: {
|
|
1488
|
+
kind: parseEnum(requireOption(args, "owner-kind"), "--owner-kind", [
|
|
1489
|
+
"agent",
|
|
1490
|
+
"company",
|
|
1491
|
+
"marketplace",
|
|
1492
|
+
"contract",
|
|
1493
|
+
"dispute"
|
|
1494
|
+
]),
|
|
1495
|
+
id: requireOption(args, "owner-id")
|
|
1496
|
+
},
|
|
1497
|
+
membershipPolicy,
|
|
1498
|
+
encryptionPolicy
|
|
1499
|
+
};
|
|
1500
|
+
const created = await appendEnvelope(context, {
|
|
1501
|
+
objectKind: "space",
|
|
1502
|
+
objectId: spaceId,
|
|
1503
|
+
eventKind: "space.created",
|
|
1504
|
+
subjectId: spaceId,
|
|
1505
|
+
payload: Protocol.spacePayloadToJson(payload),
|
|
1506
|
+
issuedAt
|
|
1507
|
+
});
|
|
1508
|
+
const membershipObjectId = `${spaceId}:${context.identityMaterial.agentIdentity.did}`;
|
|
1509
|
+
await appendEnvelope(context, {
|
|
1510
|
+
objectKind: "space-membership",
|
|
1511
|
+
objectId: membershipObjectId,
|
|
1512
|
+
eventKind: "space-membership.member-added",
|
|
1513
|
+
subjectId: membershipObjectId,
|
|
1514
|
+
payload: Protocol.spaceMembershipPayloadToJson({
|
|
1515
|
+
spaceId,
|
|
1516
|
+
memberDid: context.identityMaterial.agentIdentity.did,
|
|
1517
|
+
role: "owner"
|
|
1518
|
+
})
|
|
1519
|
+
});
|
|
1520
|
+
writeJson(io, {
|
|
1521
|
+
command: "space.create",
|
|
1522
|
+
objectId: spaceId,
|
|
1523
|
+
eventId: created.envelope.eventId,
|
|
1524
|
+
state: created.state
|
|
1525
|
+
});
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
async function handleSpaceMembershipAction(args, io, eventKind) {
|
|
1529
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1530
|
+
const spaceId = requireOption(args, "space-id");
|
|
1531
|
+
const memberDid = requireOption(args, "member-did");
|
|
1532
|
+
const objectId = getOptionalOption(args, "id") ?? `${spaceId}:${memberDid}`;
|
|
1533
|
+
await withCliContext(dataDir, async (context) => {
|
|
1534
|
+
const payload = eventKind === "space-membership.member-added"
|
|
1535
|
+
? Protocol.spaceMembershipPayloadToJson({
|
|
1536
|
+
spaceId,
|
|
1537
|
+
memberDid,
|
|
1538
|
+
role: parseEnum(getOptionalOption(args, "role") ?? "member", "--role", [
|
|
1539
|
+
"owner",
|
|
1540
|
+
"moderator",
|
|
1541
|
+
"member"
|
|
1542
|
+
])
|
|
1543
|
+
})
|
|
1544
|
+
: eventKind === "space-membership.member-role-updated"
|
|
1545
|
+
? toProtocolJsonObject({
|
|
1546
|
+
role: parseEnum(requireOption(args, "role"), "--role", ["owner", "moderator", "member"])
|
|
1547
|
+
})
|
|
1548
|
+
: {};
|
|
1549
|
+
const result = await appendEnvelope(context, {
|
|
1550
|
+
objectKind: "space-membership",
|
|
1551
|
+
objectId,
|
|
1552
|
+
eventKind,
|
|
1553
|
+
subjectId: objectId,
|
|
1554
|
+
payload
|
|
1555
|
+
});
|
|
1556
|
+
writeJson(io, {
|
|
1557
|
+
command: `space.${eventKind.split(".")[1]}`,
|
|
1558
|
+
objectId,
|
|
1559
|
+
eventId: result.envelope.eventId,
|
|
1560
|
+
state: result.state
|
|
1561
|
+
});
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1564
|
+
async function handleMessageSend(args, io) {
|
|
1565
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1566
|
+
await withCliContext(dataDir, async (context) => {
|
|
1567
|
+
const issuedAt = now();
|
|
1568
|
+
const spaceId = requireOption(args, "space-id");
|
|
1569
|
+
const activeMemberDids = listActiveSpaceMemberDids(context, spaceId);
|
|
1570
|
+
if (activeMemberDids.length === 0) {
|
|
1571
|
+
throw new Error("The target space has no active members");
|
|
1572
|
+
}
|
|
1573
|
+
const encryptedBody = await Protocol.encryptMessageForRecipients({
|
|
1574
|
+
plaintext: requireOption(args, "body"),
|
|
1575
|
+
senderDid: context.identityMaterial.agentIdentity.did,
|
|
1576
|
+
senderKeyAgreementPublicKey: context.identityMaterial.agentIdentity.keyAgreementPublicKey,
|
|
1577
|
+
senderKeyAgreementSecretKey: context.identityMaterial.keyAgreementKeyPair.secretKey,
|
|
1578
|
+
recipientDids: activeMemberDids
|
|
1579
|
+
});
|
|
1580
|
+
const payload = {
|
|
1581
|
+
spaceId,
|
|
1582
|
+
messageType: getOptionalOption(args, "message-type") ?? "text",
|
|
1583
|
+
metadata: getOptionalOption(args, "metadata-json")
|
|
1584
|
+
? parseJsonOption(args, "metadata-json")
|
|
1585
|
+
: {},
|
|
1586
|
+
encryptedBody,
|
|
1587
|
+
sentAt: issuedAt
|
|
1588
|
+
};
|
|
1589
|
+
const objectId = getOptionalOption(args, "id") ?? defaultObjectId("message", toProtocolValue({
|
|
1590
|
+
actorDid: context.identityMaterial.agentIdentity.did,
|
|
1591
|
+
issuedAt,
|
|
1592
|
+
payload: toProtocolJsonObject(payload)
|
|
1593
|
+
}));
|
|
1594
|
+
const result = await appendEnvelope(context, {
|
|
1595
|
+
objectKind: "message",
|
|
1596
|
+
objectId,
|
|
1597
|
+
eventKind: "message.sent",
|
|
1598
|
+
subjectId: objectId,
|
|
1599
|
+
payload: Protocol.messageSentPayloadToJson(payload),
|
|
1600
|
+
issuedAt
|
|
1601
|
+
});
|
|
1602
|
+
writeJson(io, {
|
|
1603
|
+
command: "message.send",
|
|
1604
|
+
objectId,
|
|
1605
|
+
eventId: result.envelope.eventId,
|
|
1606
|
+
state: result.state
|
|
1607
|
+
});
|
|
1608
|
+
});
|
|
1609
|
+
}
|
|
1610
|
+
async function handleMessageEdit(args, io) {
|
|
1611
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1612
|
+
const objectId = requireOption(args, "id");
|
|
1613
|
+
await withCliContext(dataDir, async (context) => {
|
|
1614
|
+
const current = await readRequiredState(context.repository, "message", objectId);
|
|
1615
|
+
const activeMemberDids = listActiveSpaceMemberDids(context, current.spaceId);
|
|
1616
|
+
const encryptedBody = await Protocol.encryptMessageForRecipients({
|
|
1617
|
+
plaintext: requireOption(args, "body"),
|
|
1618
|
+
senderDid: context.identityMaterial.agentIdentity.did,
|
|
1619
|
+
senderKeyAgreementPublicKey: context.identityMaterial.agentIdentity.keyAgreementPublicKey,
|
|
1620
|
+
senderKeyAgreementSecretKey: context.identityMaterial.keyAgreementKeyPair.secretKey,
|
|
1621
|
+
recipientDids: activeMemberDids
|
|
1622
|
+
});
|
|
1623
|
+
const result = await appendEnvelope(context, {
|
|
1624
|
+
objectKind: "message",
|
|
1625
|
+
objectId,
|
|
1626
|
+
eventKind: "message.edited",
|
|
1627
|
+
subjectId: objectId,
|
|
1628
|
+
payload: Protocol.messageSentPayloadToJson({
|
|
1629
|
+
spaceId: current.spaceId,
|
|
1630
|
+
messageType: current.messageType,
|
|
1631
|
+
metadata: getOptionalOption(args, "metadata-json")
|
|
1632
|
+
? parseJsonOption(args, "metadata-json")
|
|
1633
|
+
: current.metadata,
|
|
1634
|
+
encryptedBody
|
|
1635
|
+
})
|
|
1636
|
+
});
|
|
1637
|
+
writeJson(io, {
|
|
1638
|
+
command: "message.edit",
|
|
1639
|
+
objectId,
|
|
1640
|
+
eventId: result.envelope.eventId,
|
|
1641
|
+
state: result.state
|
|
1642
|
+
});
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
async function handleMessageDelete(args, io) {
|
|
1646
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1647
|
+
const objectId = requireOption(args, "id");
|
|
1648
|
+
await withCliContext(dataDir, async (context) => {
|
|
1649
|
+
const result = await appendEnvelope(context, {
|
|
1650
|
+
objectKind: "message",
|
|
1651
|
+
objectId,
|
|
1652
|
+
eventKind: "message.deleted",
|
|
1653
|
+
subjectId: objectId,
|
|
1654
|
+
payload: {}
|
|
1655
|
+
});
|
|
1656
|
+
writeJson(io, {
|
|
1657
|
+
command: "message.delete",
|
|
1658
|
+
objectId,
|
|
1659
|
+
eventId: result.envelope.eventId,
|
|
1660
|
+
state: result.state
|
|
1661
|
+
});
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
async function handleMessageReact(args, io) {
|
|
1665
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1666
|
+
const objectId = requireOption(args, "id");
|
|
1667
|
+
await withCliContext(dataDir, async (context) => {
|
|
1668
|
+
const result = await appendEnvelope(context, {
|
|
1669
|
+
objectKind: "message",
|
|
1670
|
+
objectId,
|
|
1671
|
+
eventKind: "message.reacted",
|
|
1672
|
+
subjectId: objectId,
|
|
1673
|
+
payload: {
|
|
1674
|
+
reaction: requireOption(args, "reaction")
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
writeJson(io, {
|
|
1678
|
+
command: "message.react",
|
|
1679
|
+
objectId,
|
|
1680
|
+
eventId: result.envelope.eventId,
|
|
1681
|
+
state: result.state
|
|
1682
|
+
});
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
async function handleContractEntries(args, io) {
|
|
1686
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1687
|
+
const contractId = requireOption(args, "id");
|
|
1688
|
+
await withCliContext(dataDir, async (context) => {
|
|
1689
|
+
writeJson(io, {
|
|
1690
|
+
command: "contract.entries",
|
|
1691
|
+
contractId,
|
|
1692
|
+
entries: await context.repository.listContractEntries(contractId)
|
|
1693
|
+
});
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
async function handleSpaceEntries(args, io) {
|
|
1697
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1698
|
+
const spaceId = requireOption(args, "space-id");
|
|
1699
|
+
await withCliContext(dataDir, async (context) => {
|
|
1700
|
+
writeJson(io, {
|
|
1701
|
+
command: "space.entries",
|
|
1702
|
+
spaceId,
|
|
1703
|
+
entries: await context.repository.listSpaceEntries(spaceId)
|
|
1704
|
+
});
|
|
1705
|
+
});
|
|
1706
|
+
}
|
|
1707
|
+
async function handleObjectShow(args, io) {
|
|
1708
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1709
|
+
const kind = parseEnum(requireOption(args, "kind"), "--kind", [
|
|
1710
|
+
"agent-profile",
|
|
1711
|
+
"company",
|
|
1712
|
+
"product",
|
|
1713
|
+
"listing",
|
|
1714
|
+
"request",
|
|
1715
|
+
"offer",
|
|
1716
|
+
"bid",
|
|
1717
|
+
"agreement",
|
|
1718
|
+
"feedback-credential-ref",
|
|
1719
|
+
"contract",
|
|
1720
|
+
"evidence-bundle",
|
|
1721
|
+
"oracle-attestation",
|
|
1722
|
+
"dispute-case",
|
|
1723
|
+
"space",
|
|
1724
|
+
"space-membership",
|
|
1725
|
+
"message"
|
|
1726
|
+
]);
|
|
1727
|
+
const objectId = requireOption(args, "id");
|
|
1728
|
+
await withCliContext(dataDir, async (context) => {
|
|
1729
|
+
writeJson(io, {
|
|
1730
|
+
command: "object.show",
|
|
1731
|
+
kind,
|
|
1732
|
+
objectId,
|
|
1733
|
+
state: await context.repository.readObjectState(kind, objectId)
|
|
1734
|
+
});
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1737
|
+
async function handleMarketList(args, io) {
|
|
1738
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1739
|
+
const marketplaceId = requireOption(args, "marketplace");
|
|
1740
|
+
await withCliContext(dataDir, async (context) => {
|
|
1741
|
+
writeJson(io, {
|
|
1742
|
+
command: "market.list",
|
|
1743
|
+
marketplaceId,
|
|
1744
|
+
entries: await context.repository.listMarketplaceEntries(marketplaceId)
|
|
1745
|
+
});
|
|
1746
|
+
});
|
|
1747
|
+
}
|
|
1748
|
+
async function handleServe(args, io) {
|
|
1749
|
+
const dataDir = requireOption(args, "data-dir");
|
|
1750
|
+
const logLevel = parseEnum(getOptionalOption(args, "log-level") ?? "info", "--log-level", [
|
|
1751
|
+
"debug",
|
|
1752
|
+
"info",
|
|
1753
|
+
"warn",
|
|
1754
|
+
"error"
|
|
1755
|
+
]);
|
|
1756
|
+
const bootstrap = getCsvOptionValues(args, "bootstrap");
|
|
1757
|
+
const marketplaces = getCsvOptionValues(args, "marketplace");
|
|
1758
|
+
const companyIds = getCsvOptionValues(args, "company");
|
|
1759
|
+
const connectDids = getCsvOptionValues(args, "connect-did");
|
|
1760
|
+
const connectNoiseKeys = getCsvOptionValues(args, "connect-noise-key");
|
|
1761
|
+
const exitAfterMs = getOptionalOption(args, "exit-after-ms");
|
|
1762
|
+
const watchProtocol = !hasFlag(args, "no-watch-protocol");
|
|
1763
|
+
const transportConfig = {
|
|
1764
|
+
dataDir,
|
|
1765
|
+
logLevel,
|
|
1766
|
+
...(bootstrap.length > 0 ? { bootstrap } : {})
|
|
1767
|
+
};
|
|
1768
|
+
const transport = await AgentTransport.create(transportConfig);
|
|
1769
|
+
const topics = [];
|
|
1770
|
+
const seenControlLengths = new Map();
|
|
1771
|
+
const discoveryIntervalMs = 2_000;
|
|
1772
|
+
let discoveryInterval;
|
|
1773
|
+
try {
|
|
1774
|
+
await transport.start();
|
|
1775
|
+
if (hasFlag(args, "agent-topic")) {
|
|
1776
|
+
topics.push({ kind: "agent", agentDid: transport.identity.did });
|
|
1777
|
+
}
|
|
1778
|
+
for (const marketplaceId of marketplaces) {
|
|
1779
|
+
topics.push({ kind: "marketplace", marketplaceId });
|
|
1780
|
+
}
|
|
1781
|
+
for (const companyId of companyIds) {
|
|
1782
|
+
topics.push({ kind: "company", companyId });
|
|
1783
|
+
}
|
|
1784
|
+
for (const topic of topics) {
|
|
1785
|
+
await transport.joinTopic(topic);
|
|
1786
|
+
}
|
|
1787
|
+
for (const did of connectDids) {
|
|
1788
|
+
await transport.connectToDid(did);
|
|
1789
|
+
}
|
|
1790
|
+
for (const publicKey of connectNoiseKeys) {
|
|
1791
|
+
await transport.connectToNoiseKey(publicKey);
|
|
1792
|
+
}
|
|
1793
|
+
writeJson(io, {
|
|
1794
|
+
command: "serve",
|
|
1795
|
+
identity: transport.identity,
|
|
1796
|
+
topics,
|
|
1797
|
+
connectedPeers: [...transport.getPeerSessions().values()]
|
|
1798
|
+
});
|
|
1799
|
+
if (watchProtocol) {
|
|
1800
|
+
discoveryInterval = setInterval(() => {
|
|
1801
|
+
void (async () => {
|
|
1802
|
+
for (const session of transport.getPeerSessions().values()) {
|
|
1803
|
+
const remoteFeed = transport.getRemoteFeed(session.remoteControlFeedKey);
|
|
1804
|
+
if (!remoteFeed) {
|
|
1805
|
+
continue;
|
|
1806
|
+
}
|
|
1807
|
+
await remoteFeed.update({ wait: false });
|
|
1808
|
+
const seenLength = seenControlLengths.get(session.remoteControlFeedKey) ?? 0;
|
|
1809
|
+
if (remoteFeed.length <= seenLength) {
|
|
1810
|
+
continue;
|
|
1811
|
+
}
|
|
1812
|
+
for (let index = seenLength; index < remoteFeed.length; index += 1) {
|
|
1813
|
+
const entry = await remoteFeed.get(index);
|
|
1814
|
+
if (Protocol.isProtocolAnnouncement(entry)) {
|
|
1815
|
+
io.stdout(`${JSON.stringify({ command: "serve.discovery", remoteDid: session.remoteDid, announcement: entry }, null, 2)}\n`);
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
seenControlLengths.set(session.remoteControlFeedKey, remoteFeed.length);
|
|
1819
|
+
}
|
|
1820
|
+
})().catch((error) => {
|
|
1821
|
+
io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
1822
|
+
});
|
|
1823
|
+
}, discoveryIntervalMs);
|
|
1824
|
+
}
|
|
1825
|
+
if (exitAfterMs) {
|
|
1826
|
+
await sleep(parsePositiveInteger(exitAfterMs, "--exit-after-ms"));
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
await Promise.race([once(process, "SIGINT"), once(process, "SIGTERM")]);
|
|
1830
|
+
}
|
|
1831
|
+
finally {
|
|
1832
|
+
if (discoveryInterval) {
|
|
1833
|
+
clearInterval(discoveryInterval);
|
|
1834
|
+
}
|
|
1835
|
+
await transport.stop();
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
function usage() {
|
|
1839
|
+
return [
|
|
1840
|
+
"Usage:",
|
|
1841
|
+
" emporion agent init --data-dir <path> [--display-name <name>] [--bio <text>]",
|
|
1842
|
+
" emporion agent show --data-dir <path>",
|
|
1843
|
+
" emporion agent payment-endpoint add --data-dir <path> --id <id> --capability <cap>[,<cap>...]",
|
|
1844
|
+
" emporion agent wallet-attestation add --data-dir <path> --attestation-id <id> --wallet-account-id <id> --balance-sats <n> --expires-at <iso>",
|
|
1845
|
+
" emporion agent feedback add --data-dir <path> --credential-id <id> --issuer-did <did> --contract-id <id> --agreement-id <id> --score <n> --max-score <n>",
|
|
1846
|
+
" emporion company create --data-dir <path> --name <name> [--description <text>]",
|
|
1847
|
+
" emporion company update --data-dir <path> --company-did <did> [--name <name>] [--description <text>]",
|
|
1848
|
+
" emporion company grant-role --data-dir <path> --company-did <did> --member-did <did> --role <owner|operator|member>",
|
|
1849
|
+
" emporion company treasury-attest --data-dir <path> --company-did <did> --attestation-id <id> --wallet-account-id <id> --balance-sats <n> --expires-at <iso>",
|
|
1850
|
+
" emporion market product create --data-dir <path> --marketplace <id> --title <title>",
|
|
1851
|
+
" emporion market listing publish --data-dir <path> --marketplace <id> --title <title> --amount-sats <n>",
|
|
1852
|
+
" emporion market request publish --data-dir <path> --marketplace <id> --title <title> --amount-sats <n>",
|
|
1853
|
+
" emporion market offer submit --data-dir <path> --marketplace <id> --amount-sats <n>",
|
|
1854
|
+
" emporion market bid submit --data-dir <path> --marketplace <id> --amount-sats <n>",
|
|
1855
|
+
" emporion market agreement create --data-dir <path> --source-kind <offer|bid|listing|request> --source-id <id> --deliverable <text>",
|
|
1856
|
+
" emporion contract create --data-dir <path> --origin-kind <kind> --origin-id <id> --party <did>[,<did>...] --scope <text> --milestones-json <json> --deliverable-schema-json <json> --proof-policy-json <json> --resolution-policy-json <json> --settlement-policy-json <json> --deadline-policy-json <json>",
|
|
1857
|
+
" emporion evidence record --data-dir <path> --contract-id <id> --milestone-id <id> --proof-mode <mode>[,<mode>...] [--artifact-json <json>] [--verifier-json <json>]",
|
|
1858
|
+
" emporion oracle attest --data-dir <path> --claim-type <type> --subject-kind <kind> --subject-id <id> --outcome <outcome> --expires-at <iso>",
|
|
1859
|
+
" emporion dispute open --data-dir <path> --contract-id <id> --reason <text>",
|
|
1860
|
+
" emporion space create --data-dir <path> --space-kind <kind> --owner-kind <kind> --owner-id <id>",
|
|
1861
|
+
" emporion message send --data-dir <path> --space-id <id> --body <text>",
|
|
1862
|
+
" emporion market list --data-dir <path> --marketplace <id>",
|
|
1863
|
+
" emporion object show --data-dir <path> --kind <kind> --id <id>",
|
|
1864
|
+
" emporion serve --data-dir <path> [--marketplace <id>] [--company <did>] [--agent-topic]"
|
|
1865
|
+
].join("\n");
|
|
1866
|
+
}
|
|
1867
|
+
export async function runCli(argv, io = DEFAULT_IO) {
|
|
1868
|
+
try {
|
|
1869
|
+
const args = parseArgs(argv);
|
|
1870
|
+
if (args.commandPath.length === 0 || hasFlag(args, "help")) {
|
|
1871
|
+
io.stdout(`${usage()}\n`);
|
|
1872
|
+
return 0;
|
|
1873
|
+
}
|
|
1874
|
+
if (commandMatches(args.commandPath, "agent", "init"))
|
|
1875
|
+
return await handleAgentInit(args, io).then(() => 0);
|
|
1876
|
+
if (commandMatches(args.commandPath, "agent", "show"))
|
|
1877
|
+
return await handleAgentShow(args, io).then(() => 0);
|
|
1878
|
+
if (commandMatches(args.commandPath, "agent", "payment-endpoint", "add")) {
|
|
1879
|
+
return await handleAgentPaymentEndpointAdd(args, io).then(() => 0);
|
|
1880
|
+
}
|
|
1881
|
+
if (commandMatches(args.commandPath, "agent", "payment-endpoint", "remove")) {
|
|
1882
|
+
return await handleAgentPaymentEndpointRemove(args, io).then(() => 0);
|
|
1883
|
+
}
|
|
1884
|
+
if (commandMatches(args.commandPath, "agent", "wallet-attestation", "add")) {
|
|
1885
|
+
return await handleAgentWalletAttestationAdd(args, io).then(() => 0);
|
|
1886
|
+
}
|
|
1887
|
+
if (commandMatches(args.commandPath, "agent", "wallet-attestation", "remove")) {
|
|
1888
|
+
return await handleAgentWalletAttestationRemove(args, io).then(() => 0);
|
|
1889
|
+
}
|
|
1890
|
+
if (commandMatches(args.commandPath, "agent", "feedback", "add")) {
|
|
1891
|
+
return await handleAgentFeedbackAdd(args, io).then(() => 0);
|
|
1892
|
+
}
|
|
1893
|
+
if (commandMatches(args.commandPath, "agent", "feedback", "remove")) {
|
|
1894
|
+
return await handleAgentFeedbackRemove(args, io).then(() => 0);
|
|
1895
|
+
}
|
|
1896
|
+
if (commandMatches(args.commandPath, "company", "create"))
|
|
1897
|
+
return await handleCompanyCreate(args, io).then(() => 0);
|
|
1898
|
+
if (commandMatches(args.commandPath, "company", "show"))
|
|
1899
|
+
return await handleCompanyShow(args, io).then(() => 0);
|
|
1900
|
+
if (commandMatches(args.commandPath, "company", "update"))
|
|
1901
|
+
return await handleCompanyUpdate(args, io).then(() => 0);
|
|
1902
|
+
if (commandMatches(args.commandPath, "company", "grant-role")) {
|
|
1903
|
+
return await handleCompanyRoleChange(args, io, "grant").then(() => 0);
|
|
1904
|
+
}
|
|
1905
|
+
if (commandMatches(args.commandPath, "company", "revoke-role")) {
|
|
1906
|
+
return await handleCompanyRoleChange(args, io, "revoke").then(() => 0);
|
|
1907
|
+
}
|
|
1908
|
+
if (commandMatches(args.commandPath, "company", "join-market")) {
|
|
1909
|
+
return await handleCompanyMarketMembership(args, io, "join").then(() => 0);
|
|
1910
|
+
}
|
|
1911
|
+
if (commandMatches(args.commandPath, "company", "leave-market")) {
|
|
1912
|
+
return await handleCompanyMarketMembership(args, io, "leave").then(() => 0);
|
|
1913
|
+
}
|
|
1914
|
+
if (commandMatches(args.commandPath, "company", "treasury-attest")) {
|
|
1915
|
+
return await handleCompanyTreasuryAttest(args, io).then(() => 0);
|
|
1916
|
+
}
|
|
1917
|
+
if (commandMatches(args.commandPath, "company", "treasury-reserve")) {
|
|
1918
|
+
return await handleCompanyTreasuryReserve(args, io).then(() => 0);
|
|
1919
|
+
}
|
|
1920
|
+
if (commandMatches(args.commandPath, "company", "treasury-release")) {
|
|
1921
|
+
return await handleCompanyTreasuryRelease(args, io).then(() => 0);
|
|
1922
|
+
}
|
|
1923
|
+
if (commandMatches(args.commandPath, "market", "product", "create")) {
|
|
1924
|
+
return await handleMarketProductCreate(args, io).then(() => 0);
|
|
1925
|
+
}
|
|
1926
|
+
if (commandMatches(args.commandPath, "market", "product", "update")) {
|
|
1927
|
+
return await handleMarketProductUpdate(args, io).then(() => 0);
|
|
1928
|
+
}
|
|
1929
|
+
if (commandMatches(args.commandPath, "market", "product", "publish")) {
|
|
1930
|
+
return await handleMarketProductStateChange(args, io, "product.published").then(() => 0);
|
|
1931
|
+
}
|
|
1932
|
+
if (commandMatches(args.commandPath, "market", "product", "unpublish")) {
|
|
1933
|
+
return await handleMarketProductStateChange(args, io, "product.unpublished").then(() => 0);
|
|
1934
|
+
}
|
|
1935
|
+
if (commandMatches(args.commandPath, "market", "product", "retire")) {
|
|
1936
|
+
return await handleMarketProductStateChange(args, io, "product.retired").then(() => 0);
|
|
1937
|
+
}
|
|
1938
|
+
if (commandMatches(args.commandPath, "market", "listing", "publish")) {
|
|
1939
|
+
return await handleMarketListingPublish(args, io).then(() => 0);
|
|
1940
|
+
}
|
|
1941
|
+
if (commandMatches(args.commandPath, "market", "listing", "revise")) {
|
|
1942
|
+
return await handleMarketListingRevise(args, io).then(() => 0);
|
|
1943
|
+
}
|
|
1944
|
+
if (commandMatches(args.commandPath, "market", "listing", "withdraw")) {
|
|
1945
|
+
return await handleSimpleMarketStateChange(args, io, "listing", "listing.withdrawn").then(() => 0);
|
|
1946
|
+
}
|
|
1947
|
+
if (commandMatches(args.commandPath, "market", "listing", "expire")) {
|
|
1948
|
+
return await handleSimpleMarketStateChange(args, io, "listing", "listing.expired").then(() => 0);
|
|
1949
|
+
}
|
|
1950
|
+
if (commandMatches(args.commandPath, "market", "request", "publish")) {
|
|
1951
|
+
return await handleMarketRequestPublish(args, io).then(() => 0);
|
|
1952
|
+
}
|
|
1953
|
+
if (commandMatches(args.commandPath, "market", "request", "revise")) {
|
|
1954
|
+
return await handleMarketRequestRevise(args, io).then(() => 0);
|
|
1955
|
+
}
|
|
1956
|
+
if (commandMatches(args.commandPath, "market", "request", "close")) {
|
|
1957
|
+
return await handleSimpleMarketStateChange(args, io, "request", "request.closed").then(() => 0);
|
|
1958
|
+
}
|
|
1959
|
+
if (commandMatches(args.commandPath, "market", "request", "expire")) {
|
|
1960
|
+
return await handleSimpleMarketStateChange(args, io, "request", "request.expired").then(() => 0);
|
|
1961
|
+
}
|
|
1962
|
+
if (commandMatches(args.commandPath, "market", "offer", "submit")) {
|
|
1963
|
+
return await handleMarketOfferSubmit(args, io).then(() => 0);
|
|
1964
|
+
}
|
|
1965
|
+
if (commandMatches(args.commandPath, "market", "offer", "counter")) {
|
|
1966
|
+
return await handleMarketOfferCounter(args, io).then(() => 0);
|
|
1967
|
+
}
|
|
1968
|
+
if (commandMatches(args.commandPath, "market", "offer", "accept")) {
|
|
1969
|
+
return await handleSimpleMarketStateChange(args, io, "offer", "offer.accepted").then(() => 0);
|
|
1970
|
+
}
|
|
1971
|
+
if (commandMatches(args.commandPath, "market", "offer", "reject")) {
|
|
1972
|
+
return await handleSimpleMarketStateChange(args, io, "offer", "offer.rejected").then(() => 0);
|
|
1973
|
+
}
|
|
1974
|
+
if (commandMatches(args.commandPath, "market", "offer", "cancel")) {
|
|
1975
|
+
return await handleSimpleMarketStateChange(args, io, "offer", "offer.canceled").then(() => 0);
|
|
1976
|
+
}
|
|
1977
|
+
if (commandMatches(args.commandPath, "market", "offer", "expire")) {
|
|
1978
|
+
return await handleSimpleMarketStateChange(args, io, "offer", "offer.expired").then(() => 0);
|
|
1979
|
+
}
|
|
1980
|
+
if (commandMatches(args.commandPath, "market", "bid", "submit")) {
|
|
1981
|
+
return await handleMarketBidSubmit(args, io).then(() => 0);
|
|
1982
|
+
}
|
|
1983
|
+
if (commandMatches(args.commandPath, "market", "bid", "counter")) {
|
|
1984
|
+
return await handleMarketBidCounter(args, io).then(() => 0);
|
|
1985
|
+
}
|
|
1986
|
+
if (commandMatches(args.commandPath, "market", "bid", "accept")) {
|
|
1987
|
+
return await handleSimpleMarketStateChange(args, io, "bid", "bid.accepted").then(() => 0);
|
|
1988
|
+
}
|
|
1989
|
+
if (commandMatches(args.commandPath, "market", "bid", "reject")) {
|
|
1990
|
+
return await handleSimpleMarketStateChange(args, io, "bid", "bid.rejected").then(() => 0);
|
|
1991
|
+
}
|
|
1992
|
+
if (commandMatches(args.commandPath, "market", "bid", "cancel")) {
|
|
1993
|
+
return await handleSimpleMarketStateChange(args, io, "bid", "bid.canceled").then(() => 0);
|
|
1994
|
+
}
|
|
1995
|
+
if (commandMatches(args.commandPath, "market", "bid", "expire")) {
|
|
1996
|
+
return await handleSimpleMarketStateChange(args, io, "bid", "bid.expired").then(() => 0);
|
|
1997
|
+
}
|
|
1998
|
+
if (commandMatches(args.commandPath, "market", "agreement", "create")) {
|
|
1999
|
+
return await handleMarketAgreementCreate(args, io).then(() => 0);
|
|
2000
|
+
}
|
|
2001
|
+
if (commandMatches(args.commandPath, "market", "agreement", "complete")) {
|
|
2002
|
+
return await handleSimpleMarketStateChange(args, io, "agreement", "agreement.completed").then(() => 0);
|
|
2003
|
+
}
|
|
2004
|
+
if (commandMatches(args.commandPath, "market", "agreement", "cancel")) {
|
|
2005
|
+
return await handleSimpleMarketStateChange(args, io, "agreement", "agreement.canceled").then(() => 0);
|
|
2006
|
+
}
|
|
2007
|
+
if (commandMatches(args.commandPath, "market", "agreement", "dispute")) {
|
|
2008
|
+
return await handleSimpleMarketStateChange(args, io, "agreement", "agreement.disputed").then(() => 0);
|
|
2009
|
+
}
|
|
2010
|
+
if (commandMatches(args.commandPath, "market", "list"))
|
|
2011
|
+
return await handleMarketList(args, io).then(() => 0);
|
|
2012
|
+
if (commandMatches(args.commandPath, "contract", "create"))
|
|
2013
|
+
return await handleContractCreate(args, io).then(() => 0);
|
|
2014
|
+
if (commandMatches(args.commandPath, "contract", "open-milestone")) {
|
|
2015
|
+
return await handleContractMilestoneAction(args, io, "contract.milestone-opened").then(() => 0);
|
|
2016
|
+
}
|
|
2017
|
+
if (commandMatches(args.commandPath, "contract", "submit-milestone")) {
|
|
2018
|
+
return await handleContractMilestoneAction(args, io, "contract.milestone-submitted").then(() => 0);
|
|
2019
|
+
}
|
|
2020
|
+
if (commandMatches(args.commandPath, "contract", "accept-milestone")) {
|
|
2021
|
+
return await handleContractMilestoneAction(args, io, "contract.milestone-accepted").then(() => 0);
|
|
2022
|
+
}
|
|
2023
|
+
if (commandMatches(args.commandPath, "contract", "reject-milestone")) {
|
|
2024
|
+
return await handleContractMilestoneAction(args, io, "contract.milestone-rejected").then(() => 0);
|
|
2025
|
+
}
|
|
2026
|
+
if (commandMatches(args.commandPath, "contract", "pause")) {
|
|
2027
|
+
return await handleContractStateChange(args, io, "contract.paused").then(() => 0);
|
|
2028
|
+
}
|
|
2029
|
+
if (commandMatches(args.commandPath, "contract", "resume")) {
|
|
2030
|
+
return await handleContractStateChange(args, io, "contract.resumed").then(() => 0);
|
|
2031
|
+
}
|
|
2032
|
+
if (commandMatches(args.commandPath, "contract", "complete")) {
|
|
2033
|
+
return await handleContractStateChange(args, io, "contract.completed").then(() => 0);
|
|
2034
|
+
}
|
|
2035
|
+
if (commandMatches(args.commandPath, "contract", "cancel")) {
|
|
2036
|
+
return await handleContractStateChange(args, io, "contract.canceled").then(() => 0);
|
|
2037
|
+
}
|
|
2038
|
+
if (commandMatches(args.commandPath, "contract", "dispute")) {
|
|
2039
|
+
return await handleContractStateChange(args, io, "contract.disputed").then(() => 0);
|
|
2040
|
+
}
|
|
2041
|
+
if (commandMatches(args.commandPath, "contract", "entries")) {
|
|
2042
|
+
return await handleContractEntries(args, io).then(() => 0);
|
|
2043
|
+
}
|
|
2044
|
+
if (commandMatches(args.commandPath, "evidence", "record"))
|
|
2045
|
+
return await handleEvidenceRecord(args, io).then(() => 0);
|
|
2046
|
+
if (commandMatches(args.commandPath, "oracle", "attest"))
|
|
2047
|
+
return await handleOracleAttest(args, io).then(() => 0);
|
|
2048
|
+
if (commandMatches(args.commandPath, "dispute", "open"))
|
|
2049
|
+
return await handleDisputeOpen(args, io).then(() => 0);
|
|
2050
|
+
if (commandMatches(args.commandPath, "dispute", "add-evidence")) {
|
|
2051
|
+
return await handleDisputeAddEvidence(args, io).then(() => 0);
|
|
2052
|
+
}
|
|
2053
|
+
if (commandMatches(args.commandPath, "dispute", "request-oracle")) {
|
|
2054
|
+
return await handleDisputeRequestOracle(args, io).then(() => 0);
|
|
2055
|
+
}
|
|
2056
|
+
if (commandMatches(args.commandPath, "dispute", "rule"))
|
|
2057
|
+
return await handleDisputeRule(args, io).then(() => 0);
|
|
2058
|
+
if (commandMatches(args.commandPath, "dispute", "close"))
|
|
2059
|
+
return await handleDisputeClose(args, io).then(() => 0);
|
|
2060
|
+
if (commandMatches(args.commandPath, "space", "create"))
|
|
2061
|
+
return await handleSpaceCreate(args, io).then(() => 0);
|
|
2062
|
+
if (commandMatches(args.commandPath, "space", "add-member")) {
|
|
2063
|
+
return await handleSpaceMembershipAction(args, io, "space-membership.member-added").then(() => 0);
|
|
2064
|
+
}
|
|
2065
|
+
if (commandMatches(args.commandPath, "space", "remove-member")) {
|
|
2066
|
+
return await handleSpaceMembershipAction(args, io, "space-membership.member-removed").then(() => 0);
|
|
2067
|
+
}
|
|
2068
|
+
if (commandMatches(args.commandPath, "space", "mute-member")) {
|
|
2069
|
+
return await handleSpaceMembershipAction(args, io, "space-membership.member-muted").then(() => 0);
|
|
2070
|
+
}
|
|
2071
|
+
if (commandMatches(args.commandPath, "space", "set-role")) {
|
|
2072
|
+
return await handleSpaceMembershipAction(args, io, "space-membership.member-role-updated").then(() => 0);
|
|
2073
|
+
}
|
|
2074
|
+
if (commandMatches(args.commandPath, "space", "entries"))
|
|
2075
|
+
return await handleSpaceEntries(args, io).then(() => 0);
|
|
2076
|
+
if (commandMatches(args.commandPath, "message", "send"))
|
|
2077
|
+
return await handleMessageSend(args, io).then(() => 0);
|
|
2078
|
+
if (commandMatches(args.commandPath, "message", "edit"))
|
|
2079
|
+
return await handleMessageEdit(args, io).then(() => 0);
|
|
2080
|
+
if (commandMatches(args.commandPath, "message", "delete"))
|
|
2081
|
+
return await handleMessageDelete(args, io).then(() => 0);
|
|
2082
|
+
if (commandMatches(args.commandPath, "message", "react"))
|
|
2083
|
+
return await handleMessageReact(args, io).then(() => 0);
|
|
2084
|
+
if (commandMatches(args.commandPath, "object", "show"))
|
|
2085
|
+
return await handleObjectShow(args, io).then(() => 0);
|
|
2086
|
+
if (commandMatches(args.commandPath, "serve"))
|
|
2087
|
+
return await handleServe(args, io).then(() => 0);
|
|
2088
|
+
throw new Error(`Unknown command: ${args.commandPath.join(" ")}`);
|
|
2089
|
+
}
|
|
2090
|
+
catch (error) {
|
|
2091
|
+
io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
2092
|
+
return 1;
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
const executedPath = process.argv[1] ? new URL(`file://${process.argv[1]}`).href : "";
|
|
2096
|
+
if (import.meta.url === executedPath) {
|
|
2097
|
+
void runCli(process.argv.slice(2)).then((exitCode) => {
|
|
2098
|
+
process.exitCode = exitCode;
|
|
2099
|
+
});
|
|
2100
|
+
}
|
|
2101
|
+
//# sourceMappingURL=cli.js.map
|