@sly_ai/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +17 -0
- package/dist/auth-ET55P6PZ.js +6 -0
- package/dist/chunk-RYX22XBE.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1129 -0
- package/package.json +22 -0
- package/src/commands/a2a.ts +110 -0
- package/src/commands/accounts.ts +85 -0
- package/src/commands/acp.ts +104 -0
- package/src/commands/agent-wallets.ts +127 -0
- package/src/commands/agents.ts +110 -0
- package/src/commands/ap2.ts +134 -0
- package/src/commands/env.ts +66 -0
- package/src/commands/merchants.ts +43 -0
- package/src/commands/mpp.ts +144 -0
- package/src/commands/settlement.ts +63 -0
- package/src/commands/support.ts +110 -0
- package/src/commands/ucp.ts +245 -0
- package/src/commands/wallets.ts +158 -0
- package/src/commands/x402.ts +131 -0
- package/src/index.ts +38 -0
- package/src/utils/auth.ts +14 -0
- package/src/utils/output.ts +8 -0
- package/tsconfig.json +25 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createClient
|
|
4
|
+
} from "./chunk-RYX22XBE.js";
|
|
5
|
+
|
|
6
|
+
// src/index.ts
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
|
|
9
|
+
// src/utils/output.ts
|
|
10
|
+
function output(data) {
|
|
11
|
+
console.log(JSON.stringify(data, null, 2));
|
|
12
|
+
}
|
|
13
|
+
function error(message) {
|
|
14
|
+
console.error(`Error: ${message}`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/commands/accounts.ts
|
|
19
|
+
function registerAccountsCommands(program2) {
|
|
20
|
+
const cmd = program2.command("accounts").description("Manage accounts (entities in the payment ledger)");
|
|
21
|
+
cmd.command("list").description("List accounts").option("--status <status>", "Filter by status (active, inactive, suspended)").option("--type <type>", "Filter by type (person, business)").action(async (opts) => {
|
|
22
|
+
try {
|
|
23
|
+
const sly = createClient();
|
|
24
|
+
const params = new URLSearchParams();
|
|
25
|
+
if (opts.status) params.set("status", opts.status);
|
|
26
|
+
if (opts.type) params.set("type", opts.type);
|
|
27
|
+
const qs = params.toString();
|
|
28
|
+
const result = await sly.request(`/v1/accounts${qs ? `?${qs}` : ""}`);
|
|
29
|
+
output(result);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
error(e.message);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
cmd.command("create").description("Create a new account").requiredOption("--name <name>", "Account holder name").requiredOption("--type <type>", "Account type (person, business)").option("--email <email>", "Email address").option("--metadata <json>", "Metadata as JSON string").action(async (opts) => {
|
|
35
|
+
try {
|
|
36
|
+
const sly = createClient();
|
|
37
|
+
const body = { name: opts.name, type: opts.type };
|
|
38
|
+
if (opts.email) body.email = opts.email;
|
|
39
|
+
if (opts.metadata) body.metadata = JSON.parse(opts.metadata);
|
|
40
|
+
const result = await sly.request("/v1/accounts", {
|
|
41
|
+
method: "POST",
|
|
42
|
+
body: JSON.stringify(body)
|
|
43
|
+
});
|
|
44
|
+
output(result);
|
|
45
|
+
} catch (e) {
|
|
46
|
+
error(e.message);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
cmd.command("get <id>").description("Get account details").action(async (id) => {
|
|
50
|
+
try {
|
|
51
|
+
const sly = createClient();
|
|
52
|
+
const result = await sly.request(`/v1/accounts/${id}`);
|
|
53
|
+
output(result);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
error(e.message);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
cmd.command("update <id>").description("Update an account").option("--name <name>", "New name").option("--email <email>", "New email").option("--metadata <json>", "Metadata as JSON string").action(async (id, opts) => {
|
|
59
|
+
try {
|
|
60
|
+
const sly = createClient();
|
|
61
|
+
const body = {};
|
|
62
|
+
if (opts.name) body.name = opts.name;
|
|
63
|
+
if (opts.email) body.email = opts.email;
|
|
64
|
+
if (opts.metadata) body.metadata = JSON.parse(opts.metadata);
|
|
65
|
+
const result = await sly.request(`/v1/accounts/${id}`, {
|
|
66
|
+
method: "PATCH",
|
|
67
|
+
body: JSON.stringify(body)
|
|
68
|
+
});
|
|
69
|
+
output(result);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
error(e.message);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/commands/agents.ts
|
|
77
|
+
function registerAgentsCommands(program2) {
|
|
78
|
+
const cmd = program2.command("agents").description("Manage AI agents");
|
|
79
|
+
cmd.command("create").description("Register a new AI agent under a business account").requiredOption("--account-id <accountId>", "UUID of the parent business account").requiredOption("--name <name>", "Name for the agent").option("--description <description>", "Description of what the agent does").action(async (opts) => {
|
|
80
|
+
try {
|
|
81
|
+
const sly = createClient();
|
|
82
|
+
const body = {
|
|
83
|
+
accountId: opts.accountId,
|
|
84
|
+
name: opts.name
|
|
85
|
+
};
|
|
86
|
+
if (opts.description) body.description = opts.description;
|
|
87
|
+
const result = await sly.request("/v1/agents", {
|
|
88
|
+
method: "POST",
|
|
89
|
+
body: JSON.stringify(body)
|
|
90
|
+
});
|
|
91
|
+
output(result);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
error(e.message);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
cmd.command("get <id>").description("Get agent details").action(async (id) => {
|
|
97
|
+
try {
|
|
98
|
+
const sly = createClient();
|
|
99
|
+
const result = await sly.request(`/v1/agents/${id}`);
|
|
100
|
+
output(result);
|
|
101
|
+
} catch (e) {
|
|
102
|
+
error(e.message);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
cmd.command("delete <id>").description("Delete an agent").action(async (id) => {
|
|
106
|
+
try {
|
|
107
|
+
const sly = createClient();
|
|
108
|
+
const result = await sly.request(`/v1/agents/${id}`, { method: "DELETE" });
|
|
109
|
+
output(result);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
error(e.message);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
cmd.command("verify <id>").description("Verify an agent at a KYA tier").requiredOption("--tier <tier>", "KYA verification tier (1, 2, or 3)", parseInt).action(async (id, opts) => {
|
|
115
|
+
try {
|
|
116
|
+
const sly = createClient();
|
|
117
|
+
const result = await sly.request(`/v1/agents/${id}/verify`, {
|
|
118
|
+
method: "POST",
|
|
119
|
+
body: JSON.stringify({ tier: opts.tier })
|
|
120
|
+
});
|
|
121
|
+
output(result);
|
|
122
|
+
} catch (e) {
|
|
123
|
+
error(e.message);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
cmd.command("limits <id>").description("Get spending limits and current usage for an agent").action(async (id) => {
|
|
127
|
+
try {
|
|
128
|
+
const sly = createClient();
|
|
129
|
+
const result = await sly.request(`/v1/agents/${id}/limits`);
|
|
130
|
+
output(result);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
error(e.message);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
cmd.command("transactions <id>").description("Get transaction history for an agent").option("--limit <limit>", "Max results per page", parseInt).option("--offset <offset>", "Offset for pagination", parseInt).option("--from <from>", "Filter from date (ISO 8601)").option("--to <to>", "Filter to date (ISO 8601)").action(async (id, opts) => {
|
|
136
|
+
try {
|
|
137
|
+
const sly = createClient();
|
|
138
|
+
const params = new URLSearchParams();
|
|
139
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
140
|
+
if (opts.offset) params.set("offset", String(opts.offset));
|
|
141
|
+
if (opts.from) params.set("from", opts.from);
|
|
142
|
+
if (opts.to) params.set("to", opts.to);
|
|
143
|
+
const qs = params.toString();
|
|
144
|
+
const result = await sly.request(`/v1/agents/${id}/transactions${qs ? `?${qs}` : ""}`);
|
|
145
|
+
output(result);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
error(e.message);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/commands/wallets.ts
|
|
153
|
+
function registerWalletsCommands(program2) {
|
|
154
|
+
const cmd = program2.command("wallets").description("Manage wallets");
|
|
155
|
+
cmd.command("list").description("List wallets").option("--status <status>", "Filter by status (active, frozen, depleted)").option("--owner-account-id <id>", "Filter by owner account UUID").option("--managed-by-agent-id <id>", "Filter by managing agent UUID").option("--page <page>", "Page number", parseInt).option("--limit <limit>", "Results per page", parseInt).action(async (opts) => {
|
|
156
|
+
try {
|
|
157
|
+
const sly = createClient();
|
|
158
|
+
const params = new URLSearchParams();
|
|
159
|
+
if (opts.status) params.set("status", opts.status);
|
|
160
|
+
if (opts.ownerAccountId) params.set("owner_account_id", opts.ownerAccountId);
|
|
161
|
+
if (opts.managedByAgentId) params.set("managed_by_agent_id", opts.managedByAgentId);
|
|
162
|
+
if (opts.page) params.set("page", String(opts.page));
|
|
163
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
164
|
+
const qs = params.toString();
|
|
165
|
+
const result = await sly.request(`/v1/wallets${qs ? `?${qs}` : ""}`);
|
|
166
|
+
output(result);
|
|
167
|
+
} catch (e) {
|
|
168
|
+
error(e.message);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
cmd.command("create").description("Create a new wallet for an account").requiredOption("--account-id <accountId>", "UUID of the owning account").option("--name <name>", "Human-readable wallet name").option("--blockchain <blockchain>", "Blockchain network (base, eth, polygon, avax, sol)").option("--wallet-type <walletType>", "Wallet type (internal, circle_custodial, circle_mpc)").option("--currency <currency>", "Wallet currency (USDC, EURC)").option("--managed-by-agent-id <agentId>", "UUID of managing agent").option("--purpose <purpose>", "Purpose of the wallet").action(async (opts) => {
|
|
172
|
+
try {
|
|
173
|
+
const sly = createClient();
|
|
174
|
+
const body = { accountId: opts.accountId };
|
|
175
|
+
if (opts.name) body.name = opts.name;
|
|
176
|
+
if (opts.blockchain) body.blockchain = opts.blockchain;
|
|
177
|
+
if (opts.walletType) body.walletType = opts.walletType;
|
|
178
|
+
if (opts.currency) body.currency = opts.currency;
|
|
179
|
+
if (opts.managedByAgentId) body.managedByAgentId = opts.managedByAgentId;
|
|
180
|
+
if (opts.purpose) body.purpose = opts.purpose;
|
|
181
|
+
const result = await sly.request("/v1/wallets", {
|
|
182
|
+
method: "POST",
|
|
183
|
+
body: JSON.stringify(body)
|
|
184
|
+
});
|
|
185
|
+
output(result);
|
|
186
|
+
} catch (e) {
|
|
187
|
+
error(e.message);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
cmd.command("get <id>").description("Get wallet details").action(async (id) => {
|
|
191
|
+
try {
|
|
192
|
+
const sly = createClient();
|
|
193
|
+
const result = await sly.request(`/v1/wallets/${id}`);
|
|
194
|
+
output(result);
|
|
195
|
+
} catch (e) {
|
|
196
|
+
error(e.message);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
cmd.command("balance <id>").description("Get wallet balance").action(async (id) => {
|
|
200
|
+
try {
|
|
201
|
+
const sly = createClient();
|
|
202
|
+
const result = await sly.request(`/v1/wallets/${id}/balance`);
|
|
203
|
+
output(result);
|
|
204
|
+
} catch (e) {
|
|
205
|
+
error(e.message);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
cmd.command("fund <id>").description("Add test funds to a wallet (sandbox only)").requiredOption("--amount <amount>", "Amount of test funds to add", parseFloat).option("--currency <currency>", "Currency (USDC, EURC)").option("--reference <reference>", "Reference note").action(async (id, opts) => {
|
|
209
|
+
try {
|
|
210
|
+
const sly = createClient();
|
|
211
|
+
const body = { amount: opts.amount };
|
|
212
|
+
if (opts.currency) body.currency = opts.currency;
|
|
213
|
+
if (opts.reference) body.reference = opts.reference;
|
|
214
|
+
const result = await sly.request(`/v1/wallets/${id}/test-fund`, {
|
|
215
|
+
method: "POST",
|
|
216
|
+
body: JSON.stringify(body)
|
|
217
|
+
});
|
|
218
|
+
output(result);
|
|
219
|
+
} catch (e) {
|
|
220
|
+
error(e.message);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
cmd.command("deposit <id>").description("Deposit funds into a wallet").requiredOption("--amount <amount>", "Amount to deposit", parseFloat).requiredOption("--from-account-id <accountId>", "UUID of the source account").option("--reference <reference>", "Reference note").action(async (id, opts) => {
|
|
224
|
+
try {
|
|
225
|
+
const sly = createClient();
|
|
226
|
+
const body = {
|
|
227
|
+
amount: opts.amount,
|
|
228
|
+
fromAccountId: opts.fromAccountId
|
|
229
|
+
};
|
|
230
|
+
if (opts.reference) body.reference = opts.reference;
|
|
231
|
+
const result = await sly.request(`/v1/wallets/${id}/deposit`, {
|
|
232
|
+
method: "POST",
|
|
233
|
+
body: JSON.stringify(body)
|
|
234
|
+
});
|
|
235
|
+
output(result);
|
|
236
|
+
} catch (e) {
|
|
237
|
+
error(e.message);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
cmd.command("withdraw <id>").description("Withdraw funds from a wallet").requiredOption("--amount <amount>", "Amount to withdraw", parseFloat).requiredOption("--destination-account-id <accountId>", "UUID of the destination account").option("--reference <reference>", "Reference note").action(async (id, opts) => {
|
|
241
|
+
try {
|
|
242
|
+
const sly = createClient();
|
|
243
|
+
const body = {
|
|
244
|
+
amount: opts.amount,
|
|
245
|
+
destinationAccountId: opts.destinationAccountId
|
|
246
|
+
};
|
|
247
|
+
if (opts.reference) body.reference = opts.reference;
|
|
248
|
+
const result = await sly.request(`/v1/wallets/${id}/withdraw`, {
|
|
249
|
+
method: "POST",
|
|
250
|
+
body: JSON.stringify(body)
|
|
251
|
+
});
|
|
252
|
+
output(result);
|
|
253
|
+
} catch (e) {
|
|
254
|
+
error(e.message);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/commands/settlement.ts
|
|
260
|
+
function registerSettlementCommands(program2) {
|
|
261
|
+
const cmd = program2.command("settlement").description("Manage settlements and FX quotes");
|
|
262
|
+
cmd.command("quote").description("Get a settlement quote with FX rates and fees").requiredOption("--from-currency <currency>", "Source currency (USD, BRL, MXN, USDC)").requiredOption("--to-currency <currency>", "Destination currency (USD, BRL, MXN, USDC)").requiredOption("--amount <amount>", "Amount to convert").option("--rail <rail>", "Settlement rail (pix, spei, wire, usdc)").action(async (opts) => {
|
|
263
|
+
try {
|
|
264
|
+
const sly = createClient();
|
|
265
|
+
const quote = await sly.getSettlementQuote({
|
|
266
|
+
fromCurrency: opts.fromCurrency,
|
|
267
|
+
toCurrency: opts.toCurrency,
|
|
268
|
+
amount: opts.amount,
|
|
269
|
+
rail: opts.rail
|
|
270
|
+
});
|
|
271
|
+
output(quote);
|
|
272
|
+
} catch (e) {
|
|
273
|
+
error(e.message);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
cmd.command("create").description("Execute a settlement using a quote").requiredOption("--quote-id <quoteId>", "Quote ID from settlement quote").requiredOption("--destination-account-id <accountId>", "Destination account ID").option("--metadata <json>", "Optional metadata as JSON string").action(async (opts) => {
|
|
277
|
+
try {
|
|
278
|
+
const sly = createClient();
|
|
279
|
+
const body = {
|
|
280
|
+
quoteId: opts.quoteId,
|
|
281
|
+
destinationAccountId: opts.destinationAccountId
|
|
282
|
+
};
|
|
283
|
+
if (opts.metadata) body.metadata = JSON.parse(opts.metadata);
|
|
284
|
+
const settlement = await sly.createSettlement(body);
|
|
285
|
+
output(settlement);
|
|
286
|
+
} catch (e) {
|
|
287
|
+
error(e.message);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
cmd.command("status <id>").description("Check the status of a settlement").action(async (id) => {
|
|
291
|
+
try {
|
|
292
|
+
const sly = createClient();
|
|
293
|
+
const settlement = await sly.getSettlement(id);
|
|
294
|
+
output(settlement);
|
|
295
|
+
} catch (e) {
|
|
296
|
+
error(e.message);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/commands/x402.ts
|
|
302
|
+
function registerX402Commands(program2) {
|
|
303
|
+
const cmd = program2.command("x402").description("x402 micropayment endpoints");
|
|
304
|
+
cmd.command("endpoints").description("List x402 payment endpoints").option("--status <status>", "Filter by status (active, paused, disabled)").option("--account-id <id>", "Filter by account UUID").option("--page <page>", "Page number", parseInt).option("--limit <limit>", "Results per page", parseInt).action(async (opts) => {
|
|
305
|
+
try {
|
|
306
|
+
const sly = createClient();
|
|
307
|
+
const params = new URLSearchParams();
|
|
308
|
+
if (opts.status) params.set("status", opts.status);
|
|
309
|
+
if (opts.accountId) params.set("account_id", opts.accountId);
|
|
310
|
+
if (opts.page) params.set("page", String(opts.page));
|
|
311
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
312
|
+
const qs = params.toString();
|
|
313
|
+
const result = await sly.request(`/v1/x402/endpoints${qs ? `?${qs}` : ""}`);
|
|
314
|
+
output(result);
|
|
315
|
+
} catch (e) {
|
|
316
|
+
error(e.message);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
cmd.command("get-endpoint <id>").description("Get x402 endpoint details").action(async (id) => {
|
|
320
|
+
try {
|
|
321
|
+
const sly = createClient();
|
|
322
|
+
const result = await sly.request(`/v1/x402/endpoints/${id}`);
|
|
323
|
+
output(result);
|
|
324
|
+
} catch (e) {
|
|
325
|
+
error(e.message);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
cmd.command("create-endpoint").description("Register an x402 payment endpoint").requiredOption("--name <name>", "Endpoint name").requiredOption("--path <path>", "API path (must start with /)").requiredOption("--method <method>", "HTTP method (GET, POST, PUT, DELETE, PATCH, ANY)").requiredOption("--account-id <accountId>", "UUID of the account receiving payments").requiredOption("--base-price <price>", "Price per request in token units", parseFloat).option("--currency <currency>", "Payment currency (USDC, EURC)").option("--description <description>", "What this endpoint provides").option("--webhook-url <url>", "URL to notify on payment").option("--network <network>", "Blockchain network").action(async (opts) => {
|
|
329
|
+
try {
|
|
330
|
+
const sly = createClient();
|
|
331
|
+
const body = {
|
|
332
|
+
name: opts.name,
|
|
333
|
+
path: opts.path,
|
|
334
|
+
method: opts.method,
|
|
335
|
+
accountId: opts.accountId,
|
|
336
|
+
basePrice: opts.basePrice
|
|
337
|
+
};
|
|
338
|
+
if (opts.currency) body.currency = opts.currency;
|
|
339
|
+
if (opts.description) body.description = opts.description;
|
|
340
|
+
if (opts.webhookUrl) body.webhookUrl = opts.webhookUrl;
|
|
341
|
+
if (opts.network) body.network = opts.network;
|
|
342
|
+
const result = await sly.request("/v1/x402/endpoints", {
|
|
343
|
+
method: "POST",
|
|
344
|
+
body: JSON.stringify(body)
|
|
345
|
+
});
|
|
346
|
+
output(result);
|
|
347
|
+
} catch (e) {
|
|
348
|
+
error(e.message);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
cmd.command("pay").description("Make an x402 micropayment to a paid endpoint").requiredOption("--endpoint-id <endpointId>", "UUID of the x402 endpoint to pay").requiredOption("--wallet-id <walletId>", "UUID of the wallet to pay from").requiredOption("--amount <amount>", "Payment amount", parseFloat).requiredOption("--currency <currency>", "Payment currency (USDC, EURC)").requiredOption("--method <method>", "HTTP method of the request being paid for").requiredOption("--path <path>", "Path of the request being paid for").action(async (opts) => {
|
|
352
|
+
try {
|
|
353
|
+
const sly = createClient();
|
|
354
|
+
const result = await sly.request("/v1/x402/payments", {
|
|
355
|
+
method: "POST",
|
|
356
|
+
body: JSON.stringify({
|
|
357
|
+
endpointId: opts.endpointId,
|
|
358
|
+
walletId: opts.walletId,
|
|
359
|
+
amount: opts.amount,
|
|
360
|
+
currency: opts.currency,
|
|
361
|
+
method: opts.method,
|
|
362
|
+
path: opts.path
|
|
363
|
+
})
|
|
364
|
+
});
|
|
365
|
+
output(result);
|
|
366
|
+
} catch (e) {
|
|
367
|
+
error(e.message);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
cmd.command("verify").description("Verify an x402 payment").option("--jwt <jwt>", "JWT payment proof for fast verification").option("--request-id <requestId>", "Request ID for database verification").option("--transfer-id <transferId>", "Transfer ID for database verification").action(async (opts) => {
|
|
371
|
+
try {
|
|
372
|
+
const sly = createClient();
|
|
373
|
+
const body = {};
|
|
374
|
+
if (opts.jwt) body.jwt = opts.jwt;
|
|
375
|
+
if (opts.requestId) body.requestId = opts.requestId;
|
|
376
|
+
if (opts.transferId) body.transferId = opts.transferId;
|
|
377
|
+
const result = await sly.request("/v1/x402/verify", {
|
|
378
|
+
method: "POST",
|
|
379
|
+
body: JSON.stringify(body)
|
|
380
|
+
});
|
|
381
|
+
output(result);
|
|
382
|
+
} catch (e) {
|
|
383
|
+
error(e.message);
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// src/commands/ap2.ts
|
|
389
|
+
function registerAP2Commands(program2) {
|
|
390
|
+
const cmd = program2.command("ap2").description("AP2 (Agent-to-Agent Protocol) mandate-based payments");
|
|
391
|
+
cmd.command("mandates").description("List mandates").option("--status <status>", "Filter by status (active, completed, cancelled, expired)").option("--agent-id <agentId>", "Filter by agent ID").option("--account-id <accountId>", "Filter by account ID").option("--limit <limit>", "Max results", parseInt).action(async (opts) => {
|
|
392
|
+
try {
|
|
393
|
+
const sly = createClient();
|
|
394
|
+
const result = await sly.ap2.listMandates({
|
|
395
|
+
status: opts.status,
|
|
396
|
+
agent_id: opts.agentId,
|
|
397
|
+
account_id: opts.accountId,
|
|
398
|
+
limit: opts.limit
|
|
399
|
+
});
|
|
400
|
+
output(result);
|
|
401
|
+
} catch (e) {
|
|
402
|
+
error(e.message);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
cmd.command("get <mandateId>").description("Get mandate details with execution history").action(async (mandateId) => {
|
|
406
|
+
try {
|
|
407
|
+
const sly = createClient();
|
|
408
|
+
const result = await sly.ap2.getMandate(mandateId);
|
|
409
|
+
output(result);
|
|
410
|
+
} catch (e) {
|
|
411
|
+
error(e.message);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
cmd.command("create").description("Create a spending mandate for an agent").requiredOption("--mandate-id <mandateId>", "Unique mandate identifier").requiredOption("--agent-id <agentId>", "UUID of the agent").requiredOption("--account-id <accountId>", "UUID of the funding account").requiredOption("--authorized-amount <amount>", "Maximum spending amount", parseFloat).option("--currency <currency>", "Currency (default: USD)").option("--mandate-type <type>", "Type: intent, cart, or payment (default: payment)").option("--description <description>", "Human-readable description").option("--expires-at <date>", "ISO 8601 expiration timestamp").option("--metadata <json>", "Metadata as JSON string").action(async (opts) => {
|
|
415
|
+
try {
|
|
416
|
+
const sly = createClient();
|
|
417
|
+
const body = {
|
|
418
|
+
mandate_id: opts.mandateId,
|
|
419
|
+
agent_id: opts.agentId,
|
|
420
|
+
account_id: opts.accountId,
|
|
421
|
+
authorized_amount: opts.authorizedAmount
|
|
422
|
+
};
|
|
423
|
+
if (opts.currency) body.currency = opts.currency;
|
|
424
|
+
if (opts.mandateType) body.mandate_type = opts.mandateType;
|
|
425
|
+
if (opts.description) body.description = opts.description;
|
|
426
|
+
if (opts.expiresAt) body.expires_at = opts.expiresAt;
|
|
427
|
+
if (opts.metadata) body.metadata = JSON.parse(opts.metadata);
|
|
428
|
+
const result = await sly.ap2.createMandate(body);
|
|
429
|
+
output(result);
|
|
430
|
+
} catch (e) {
|
|
431
|
+
error(e.message);
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
cmd.command("execute <mandateId>").description("Execute a payment against a mandate").requiredOption("--amount <amount>", "Amount to pay", parseFloat).option("--currency <currency>", "Currency").option("--description <description>", "Description of this payment").action(async (mandateId, opts) => {
|
|
435
|
+
try {
|
|
436
|
+
const sly = createClient();
|
|
437
|
+
const body = { amount: opts.amount };
|
|
438
|
+
if (opts.currency) body.currency = opts.currency;
|
|
439
|
+
if (opts.description) body.description = opts.description;
|
|
440
|
+
const result = await sly.ap2.executeMandate(mandateId, body);
|
|
441
|
+
output(result);
|
|
442
|
+
} catch (e) {
|
|
443
|
+
error(e.message);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
cmd.command("cancel <mandateId>").description("Cancel an active mandate").action(async (mandateId) => {
|
|
447
|
+
try {
|
|
448
|
+
const sly = createClient();
|
|
449
|
+
const result = await sly.ap2.cancelMandate(mandateId);
|
|
450
|
+
output(result);
|
|
451
|
+
} catch (e) {
|
|
452
|
+
error(e.message);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
cmd.command("update <mandateId>").description("Update a mandate").option("--authorized-amount <amount>", "New authorized amount", parseFloat).option("--status <status>", "New status").option("--expires-at <date>", "New expiration (ISO 8601)").option("--description <description>", "Updated description").option("--metadata <json>", "Updated metadata as JSON string").action(async (mandateId, opts) => {
|
|
456
|
+
try {
|
|
457
|
+
const sly = createClient();
|
|
458
|
+
const body = {};
|
|
459
|
+
if (opts.authorizedAmount !== void 0) body.authorized_amount = opts.authorizedAmount;
|
|
460
|
+
if (opts.status) body.status = opts.status;
|
|
461
|
+
if (opts.expiresAt) body.expires_at = opts.expiresAt;
|
|
462
|
+
if (opts.description) body.description = opts.description;
|
|
463
|
+
if (opts.metadata) body.metadata = JSON.parse(opts.metadata);
|
|
464
|
+
const result = await sly.request(`/v1/ap2/mandates/${mandateId}`, {
|
|
465
|
+
method: "PATCH",
|
|
466
|
+
body: JSON.stringify(body)
|
|
467
|
+
});
|
|
468
|
+
output(result);
|
|
469
|
+
} catch (e) {
|
|
470
|
+
error(e.message);
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/commands/acp.ts
|
|
476
|
+
function registerACPCommands(program2) {
|
|
477
|
+
const cmd = program2.command("acp").description("ACP (Agentic Commerce Protocol) checkout-based payments");
|
|
478
|
+
cmd.command("checkouts").description("List ACP checkouts").option("--status <status>", "Filter by status (pending, completed, cancelled, expired)").option("--agent-id <agentId>", "Filter by agent ID").option("--merchant-id <merchantId>", "Filter by merchant ID").option("--limit <limit>", "Max results", parseInt).action(async (opts) => {
|
|
479
|
+
try {
|
|
480
|
+
const sly = createClient();
|
|
481
|
+
const result = await sly.acp.listCheckouts({
|
|
482
|
+
status: opts.status,
|
|
483
|
+
agent_id: opts.agentId,
|
|
484
|
+
merchant_id: opts.merchantId,
|
|
485
|
+
limit: opts.limit
|
|
486
|
+
});
|
|
487
|
+
output(result);
|
|
488
|
+
} catch (e) {
|
|
489
|
+
error(e.message);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
cmd.command("get <checkoutId>").description("Get checkout details").action(async (checkoutId) => {
|
|
493
|
+
try {
|
|
494
|
+
const sly = createClient();
|
|
495
|
+
const result = await sly.acp.getCheckout(checkoutId);
|
|
496
|
+
output(result);
|
|
497
|
+
} catch (e) {
|
|
498
|
+
error(e.message);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
cmd.command("create").description("Create a checkout session").requiredOption("--checkout-id <checkoutId>", "Unique checkout identifier").requiredOption("--agent-id <agentId>", "UUID of the agent").requiredOption("--merchant-id <merchantId>", "Merchant identifier").requiredOption("--items <json>", "Items as JSON array").option("--account-id <accountId>", "UUID of the funding account").option("--tax-amount <amount>", "Tax amount", parseFloat).option("--shipping-amount <amount>", "Shipping amount", parseFloat).option("--payment-method <method>", "Payment method").action(async (opts) => {
|
|
502
|
+
try {
|
|
503
|
+
const sly = createClient();
|
|
504
|
+
const body = {
|
|
505
|
+
checkout_id: opts.checkoutId,
|
|
506
|
+
agent_id: opts.agentId,
|
|
507
|
+
merchant_id: opts.merchantId,
|
|
508
|
+
items: JSON.parse(opts.items)
|
|
509
|
+
};
|
|
510
|
+
if (opts.accountId) body.account_id = opts.accountId;
|
|
511
|
+
if (opts.taxAmount !== void 0) body.tax_amount = opts.taxAmount;
|
|
512
|
+
if (opts.shippingAmount !== void 0) body.shipping_amount = opts.shippingAmount;
|
|
513
|
+
if (opts.paymentMethod) body.payment_method = opts.paymentMethod;
|
|
514
|
+
const result = await sly.acp.createCheckout(body);
|
|
515
|
+
output(result);
|
|
516
|
+
} catch (e) {
|
|
517
|
+
error(e.message);
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
cmd.command("complete <checkoutId>").description("Complete and pay for a checkout").option("--shared-payment-token <token>", "Shared payment token (auto-generated in sandbox)").option("--payment-method <method>", "Payment method").action(async (checkoutId, opts) => {
|
|
521
|
+
try {
|
|
522
|
+
const sly = createClient();
|
|
523
|
+
const body = {};
|
|
524
|
+
if (opts.sharedPaymentToken) body.shared_payment_token = opts.sharedPaymentToken;
|
|
525
|
+
if (opts.paymentMethod) body.payment_method = opts.paymentMethod;
|
|
526
|
+
const result = await sly.acp.completeCheckout(checkoutId, body);
|
|
527
|
+
output(result);
|
|
528
|
+
} catch (e) {
|
|
529
|
+
error(e.message);
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
cmd.command("cancel <checkoutId>").description("Cancel a checkout").action(async (checkoutId) => {
|
|
533
|
+
try {
|
|
534
|
+
const sly = createClient();
|
|
535
|
+
const result = await sly.acp.cancelCheckout(checkoutId);
|
|
536
|
+
output(result);
|
|
537
|
+
} catch (e) {
|
|
538
|
+
error(e.message);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// src/commands/ucp.ts
|
|
544
|
+
function registerUCPCommands(program2) {
|
|
545
|
+
const cmd = program2.command("ucp").description("UCP (Universal Commerce Protocol) operations");
|
|
546
|
+
cmd.command("discover <merchantUrl>").description("Discover a UCP merchant's capabilities").action(async (merchantUrl) => {
|
|
547
|
+
try {
|
|
548
|
+
const sly = createClient();
|
|
549
|
+
const result = await sly.request("/v1/ucp/discover", {
|
|
550
|
+
method: "POST",
|
|
551
|
+
body: JSON.stringify({ merchantUrl })
|
|
552
|
+
});
|
|
553
|
+
output(result);
|
|
554
|
+
} catch (e) {
|
|
555
|
+
error(e.message);
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
cmd.command("checkouts").description("List UCP checkout sessions").option("--status <status>", "Filter by status").option("--agent-id <agentId>", "Filter by agent ID").option("--page <page>", "Page number", parseInt).option("--limit <limit>", "Results per page", parseInt).action(async (opts) => {
|
|
559
|
+
try {
|
|
560
|
+
const sly = createClient();
|
|
561
|
+
const params = new URLSearchParams();
|
|
562
|
+
if (opts.status) params.set("status", opts.status);
|
|
563
|
+
if (opts.agentId) params.set("agent_id", opts.agentId);
|
|
564
|
+
if (opts.page) params.set("page", String(opts.page));
|
|
565
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
566
|
+
const qs = params.toString();
|
|
567
|
+
const result = await sly.request(`/v1/ucp/checkouts${qs ? `?${qs}` : ""}`);
|
|
568
|
+
output(result);
|
|
569
|
+
} catch (e) {
|
|
570
|
+
error(e.message);
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
cmd.command("create-checkout").description("Create a UCP checkout session").requiredOption("--currency <currency>", "ISO 4217 pricing currency (e.g., USD)").requiredOption("--line-items <json>", "Line items as JSON array").option("--buyer <json>", "Buyer info as JSON").option("--shipping-address <json>", "Shipping address as JSON").option("--checkout-type <type>", "Checkout type (physical, digital, service)").option("--agent-id <agentId>", "Agent ID to attribute this checkout to").option("--metadata <json>", "Custom metadata as JSON").action(async (opts) => {
|
|
574
|
+
try {
|
|
575
|
+
const sly = createClient();
|
|
576
|
+
const body = {
|
|
577
|
+
currency: opts.currency,
|
|
578
|
+
line_items: JSON.parse(opts.lineItems)
|
|
579
|
+
};
|
|
580
|
+
if (opts.buyer) body.buyer = JSON.parse(opts.buyer);
|
|
581
|
+
if (opts.shippingAddress) body.shipping_address = JSON.parse(opts.shippingAddress);
|
|
582
|
+
if (opts.checkoutType) body.checkout_type = opts.checkoutType;
|
|
583
|
+
if (opts.agentId) body.agent_id = opts.agentId;
|
|
584
|
+
if (opts.metadata) body.metadata = JSON.parse(opts.metadata);
|
|
585
|
+
const result = await sly.request("/v1/ucp/checkouts", {
|
|
586
|
+
method: "POST",
|
|
587
|
+
body: JSON.stringify(body)
|
|
588
|
+
});
|
|
589
|
+
output(result);
|
|
590
|
+
} catch (e) {
|
|
591
|
+
error(e.message);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
cmd.command("get-checkout <id>").description("Get UCP checkout details").action(async (id) => {
|
|
595
|
+
try {
|
|
596
|
+
const sly = createClient();
|
|
597
|
+
const result = await sly.request(`/v1/ucp/checkouts/${id}`);
|
|
598
|
+
output(result);
|
|
599
|
+
} catch (e) {
|
|
600
|
+
error(e.message);
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
cmd.command("complete-checkout <id>").description("Complete a UCP checkout").action(async (id) => {
|
|
604
|
+
try {
|
|
605
|
+
const sly = createClient();
|
|
606
|
+
const result = await sly.request(`/v1/ucp/checkouts/${id}/complete`, {
|
|
607
|
+
method: "POST"
|
|
608
|
+
});
|
|
609
|
+
output(result);
|
|
610
|
+
} catch (e) {
|
|
611
|
+
error(e.message);
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
cmd.command("cancel-checkout <id>").description("Cancel a UCP checkout session").action(async (id) => {
|
|
615
|
+
try {
|
|
616
|
+
const sly = createClient();
|
|
617
|
+
const result = await sly.request(`/v1/ucp/checkouts/${id}/cancel`, {
|
|
618
|
+
method: "POST"
|
|
619
|
+
});
|
|
620
|
+
output(result);
|
|
621
|
+
} catch (e) {
|
|
622
|
+
error(e.message);
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
cmd.command("add-instrument <checkoutId>").description("Add a payment instrument to a UCP checkout").requiredOption("--instrument-id <id>", "Unique instrument identifier").requiredOption("--handler <handler>", "Payment handler (e.g., sly)").requiredOption("--type <type>", "Instrument type (e.g., usdc)").option("--last4 <last4>", "Last 4 digits").option("--brand <brand>", "Brand name").action(async (checkoutId, opts) => {
|
|
626
|
+
try {
|
|
627
|
+
const sly = createClient();
|
|
628
|
+
const body = {
|
|
629
|
+
id: opts.instrumentId,
|
|
630
|
+
handler: opts.handler,
|
|
631
|
+
type: opts.type
|
|
632
|
+
};
|
|
633
|
+
if (opts.last4) body.last4 = opts.last4;
|
|
634
|
+
if (opts.brand) body.brand = opts.brand;
|
|
635
|
+
const result = await sly.request(`/v1/ucp/checkouts/${checkoutId}/instruments`, {
|
|
636
|
+
method: "POST",
|
|
637
|
+
body: JSON.stringify(body)
|
|
638
|
+
});
|
|
639
|
+
output(result);
|
|
640
|
+
} catch (e) {
|
|
641
|
+
error(e.message);
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
cmd.command("orders").description("List UCP orders").option("--status <status>", "Filter by order status").option("--agent-id <agentId>", "Filter by agent ID").option("--page <page>", "Page number", parseInt).option("--limit <limit>", "Results per page", parseInt).action(async (opts) => {
|
|
645
|
+
try {
|
|
646
|
+
const sly = createClient();
|
|
647
|
+
const params = new URLSearchParams();
|
|
648
|
+
if (opts.status) params.set("status", opts.status);
|
|
649
|
+
if (opts.agentId) params.set("agent_id", opts.agentId);
|
|
650
|
+
if (opts.page) params.set("page", String(opts.page));
|
|
651
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
652
|
+
const qs = params.toString();
|
|
653
|
+
const result = await sly.request(`/v1/ucp/orders${qs ? `?${qs}` : ""}`);
|
|
654
|
+
output(result);
|
|
655
|
+
} catch (e) {
|
|
656
|
+
error(e.message);
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
cmd.command("get-order <id>").description("Get UCP order details").action(async (id) => {
|
|
660
|
+
try {
|
|
661
|
+
const sly = createClient();
|
|
662
|
+
const result = await sly.request(`/v1/ucp/orders/${id}`);
|
|
663
|
+
output(result);
|
|
664
|
+
} catch (e) {
|
|
665
|
+
error(e.message);
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
cmd.command("update-order-status <orderId>").description("Update UCP order status").requiredOption("--status <status>", "New order status (processing, shipped, delivered)").action(async (orderId, opts) => {
|
|
669
|
+
try {
|
|
670
|
+
const sly = createClient();
|
|
671
|
+
const result = await sly.request(`/v1/ucp/orders/${orderId}/status`, {
|
|
672
|
+
method: "PUT",
|
|
673
|
+
body: JSON.stringify({ status: opts.status })
|
|
674
|
+
});
|
|
675
|
+
output(result);
|
|
676
|
+
} catch (e) {
|
|
677
|
+
error(e.message);
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
cmd.command("cancel-order <orderId>").description("Cancel a UCP order").option("--reason <reason>", "Cancellation reason").action(async (orderId, opts) => {
|
|
681
|
+
try {
|
|
682
|
+
const sly = createClient();
|
|
683
|
+
const result = await sly.request(`/v1/ucp/orders/${orderId}/cancel`, {
|
|
684
|
+
method: "POST",
|
|
685
|
+
body: JSON.stringify({ reason: opts.reason })
|
|
686
|
+
});
|
|
687
|
+
output(result);
|
|
688
|
+
} catch (e) {
|
|
689
|
+
error(e.message);
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
cmd.command("add-event <orderId>").description("Record a fulfillment event on a UCP order").requiredOption("--type <type>", "Event type (shipped, in_transit, out_for_delivery, delivered, returned)").requiredOption("--description <description>", "Event description").option("--tracking-number <trackingNumber>", "Tracking number").option("--carrier <carrier>", "Shipping carrier").action(async (orderId, opts) => {
|
|
693
|
+
try {
|
|
694
|
+
const sly = createClient();
|
|
695
|
+
const body = {
|
|
696
|
+
type: opts.type,
|
|
697
|
+
description: opts.description
|
|
698
|
+
};
|
|
699
|
+
if (opts.trackingNumber) body.tracking_number = opts.trackingNumber;
|
|
700
|
+
if (opts.carrier) body.carrier = opts.carrier;
|
|
701
|
+
const result = await sly.request(`/v1/ucp/orders/${orderId}/events`, {
|
|
702
|
+
method: "POST",
|
|
703
|
+
body: JSON.stringify(body)
|
|
704
|
+
});
|
|
705
|
+
output(result);
|
|
706
|
+
} catch (e) {
|
|
707
|
+
error(e.message);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// src/commands/mpp.ts
|
|
713
|
+
function registerMPPCommands(program2) {
|
|
714
|
+
const cmd = program2.command("mpp").description("MPP (Machine Payments Protocol) sessions and payments");
|
|
715
|
+
cmd.command("sessions").description("List MPP sessions").option("--agent-id <agentId>", "Filter by agent ID").option("--status <status>", "Filter by status (active, closed, expired, exhausted)").option("--limit <limit>", "Results per page", parseInt).option("--offset <offset>", "Offset for pagination", parseInt).action(async (opts) => {
|
|
716
|
+
try {
|
|
717
|
+
const sly = createClient();
|
|
718
|
+
const result = await sly.mpp.listSessions({
|
|
719
|
+
agent_id: opts.agentId,
|
|
720
|
+
status: opts.status,
|
|
721
|
+
limit: opts.limit,
|
|
722
|
+
offset: opts.offset
|
|
723
|
+
});
|
|
724
|
+
output(result);
|
|
725
|
+
} catch (e) {
|
|
726
|
+
error(e.message);
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
cmd.command("get-session <id>").description("Get MPP session details with voucher history").action(async (id) => {
|
|
730
|
+
try {
|
|
731
|
+
const sly = createClient();
|
|
732
|
+
const result = await sly.mpp.getSession(id);
|
|
733
|
+
output(result);
|
|
734
|
+
} catch (e) {
|
|
735
|
+
error(e.message);
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
cmd.command("open").description("Open a streaming MPP payment session").requiredOption("--service-url <url>", "URL of the service").requiredOption("--deposit-amount <amount>", "Initial deposit amount", parseFloat).requiredOption("--agent-id <agentId>", "UUID of the agent").requiredOption("--wallet-id <walletId>", "UUID of the wallet").option("--max-budget <amount>", "Maximum total budget", parseFloat).option("--currency <currency>", "Currency (default: USDC)").action(async (opts) => {
|
|
739
|
+
try {
|
|
740
|
+
const sly = createClient();
|
|
741
|
+
const body = {
|
|
742
|
+
service_url: opts.serviceUrl,
|
|
743
|
+
deposit_amount: opts.depositAmount,
|
|
744
|
+
agent_id: opts.agentId,
|
|
745
|
+
wallet_id: opts.walletId
|
|
746
|
+
};
|
|
747
|
+
if (opts.maxBudget !== void 0) body.max_budget = opts.maxBudget;
|
|
748
|
+
if (opts.currency) body.currency = opts.currency;
|
|
749
|
+
const result = await sly.mpp.openSession(body);
|
|
750
|
+
output(result);
|
|
751
|
+
} catch (e) {
|
|
752
|
+
error(e.message);
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
cmd.command("pay").description("Make a one-shot MPP payment to a service").requiredOption("--service-url <url>", "URL of the service to pay").requiredOption("--amount <amount>", "Payment amount", parseFloat).requiredOption("--agent-id <agentId>", "UUID of the agent making the payment").option("--wallet-id <walletId>", "UUID of the wallet to pay from").option("--currency <currency>", "Currency (default: USDC)").option("--intent <intent>", "Description of what the payment is for").action(async (opts) => {
|
|
756
|
+
try {
|
|
757
|
+
const sly = createClient();
|
|
758
|
+
const body = {
|
|
759
|
+
service_url: opts.serviceUrl,
|
|
760
|
+
amount: opts.amount,
|
|
761
|
+
agent_id: opts.agentId
|
|
762
|
+
};
|
|
763
|
+
if (opts.walletId) body.wallet_id = opts.walletId;
|
|
764
|
+
if (opts.currency) body.currency = opts.currency;
|
|
765
|
+
if (opts.intent) body.intent = opts.intent;
|
|
766
|
+
const result = await sly.mpp.pay(body);
|
|
767
|
+
output(result);
|
|
768
|
+
} catch (e) {
|
|
769
|
+
error(e.message);
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
cmd.command("close <sessionId>").description("Close an active MPP session").action(async (sessionId) => {
|
|
773
|
+
try {
|
|
774
|
+
const sly = createClient();
|
|
775
|
+
const result = await sly.mpp.closeSession(sessionId);
|
|
776
|
+
output(result);
|
|
777
|
+
} catch (e) {
|
|
778
|
+
error(e.message);
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
cmd.command("transfers").description("List MPP payment transfers").option("--service-url <url>", "Filter by service URL").option("--session-id <id>", "Filter by session ID").option("--limit <limit>", "Results per page", parseInt).option("--offset <offset>", "Offset for pagination", parseInt).action(async (opts) => {
|
|
782
|
+
try {
|
|
783
|
+
const sly = createClient();
|
|
784
|
+
const result = await sly.mpp.listTransfers({
|
|
785
|
+
service_url: opts.serviceUrl,
|
|
786
|
+
session_id: opts.sessionId,
|
|
787
|
+
limit: opts.limit,
|
|
788
|
+
offset: opts.offset
|
|
789
|
+
});
|
|
790
|
+
output(result);
|
|
791
|
+
} catch (e) {
|
|
792
|
+
error(e.message);
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
cmd.command("verify-receipt <receiptId>").description("Verify an MPP payment receipt").action(async (receiptId) => {
|
|
796
|
+
try {
|
|
797
|
+
const sly = createClient();
|
|
798
|
+
const result = await sly.mpp.verifyReceipt(receiptId);
|
|
799
|
+
output(result);
|
|
800
|
+
} catch (e) {
|
|
801
|
+
error(e.message);
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// src/commands/a2a.ts
|
|
807
|
+
function registerA2ACommands(program2) {
|
|
808
|
+
const cmd = program2.command("a2a").description("A2A (Agent-to-Agent Protocol) task management");
|
|
809
|
+
cmd.command("discover <agentId>").description("Discover an agent's capabilities via its Agent Card").action(async (agentId) => {
|
|
810
|
+
try {
|
|
811
|
+
const sly = createClient();
|
|
812
|
+
const result = await sly.a2a.discover(agentId);
|
|
813
|
+
output(result);
|
|
814
|
+
} catch (e) {
|
|
815
|
+
error(e.message);
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
cmd.command("send").description("Send a message to an A2A agent").requiredOption("--agent-id <agentId>", "Local Sly agent ID").requiredOption("--message <message>", "Text message to send to the agent").option("--context-id <contextId>", "Context ID for multi-turn conversations").option("--skill-id <skillId>", "Skill ID to target").action(async (opts) => {
|
|
819
|
+
try {
|
|
820
|
+
const sly = createClient();
|
|
821
|
+
const result = await sly.a2a.sendMessage(opts.agentId, {
|
|
822
|
+
message: opts.message,
|
|
823
|
+
contextId: opts.contextId,
|
|
824
|
+
skillId: opts.skillId
|
|
825
|
+
});
|
|
826
|
+
output(result);
|
|
827
|
+
} catch (e) {
|
|
828
|
+
error(e.message);
|
|
829
|
+
}
|
|
830
|
+
});
|
|
831
|
+
cmd.command("get-task").description("Get the status and details of an A2A task").requiredOption("--agent-id <agentId>", "Agent ID").requiredOption("--task-id <taskId>", "Task ID").option("--history-length <length>", "Number of history items to include", parseInt).action(async (opts) => {
|
|
832
|
+
try {
|
|
833
|
+
const sly = createClient();
|
|
834
|
+
const result = await sly.a2a.getTask(opts.agentId, opts.taskId, opts.historyLength);
|
|
835
|
+
output(result);
|
|
836
|
+
} catch (e) {
|
|
837
|
+
error(e.message);
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
cmd.command("tasks").description("List A2A tasks").option("--agent-id <agentId>", "Filter by agent ID").option("--state <state>", "Filter by state (submitted, working, input-required, completed, failed, canceled, rejected)").option("--direction <direction>", "Filter by direction (inbound, outbound)").option("--limit <limit>", "Results per page", parseInt).option("--page <page>", "Page number", parseInt).action(async (opts) => {
|
|
841
|
+
try {
|
|
842
|
+
const sly = createClient();
|
|
843
|
+
const result = await sly.a2a.listTasks({
|
|
844
|
+
agentId: opts.agentId,
|
|
845
|
+
state: opts.state,
|
|
846
|
+
direction: opts.direction,
|
|
847
|
+
limit: opts.limit,
|
|
848
|
+
page: opts.page
|
|
849
|
+
});
|
|
850
|
+
output(result);
|
|
851
|
+
} catch (e) {
|
|
852
|
+
error(e.message);
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
cmd.command("respond <taskId>").description("Respond to a task in input-required state").requiredOption("--message <message>", "Response message").action(async (taskId, opts) => {
|
|
856
|
+
try {
|
|
857
|
+
const sly = createClient();
|
|
858
|
+
const result = await sly.a2a.respond(taskId, opts.message);
|
|
859
|
+
output(result);
|
|
860
|
+
} catch (e) {
|
|
861
|
+
error(e.message);
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
cmd.command("cancel").description("Cancel an A2A task").requiredOption("--agent-id <agentId>", "Agent ID").requiredOption("--task-id <taskId>", "Task ID").action(async (opts) => {
|
|
865
|
+
try {
|
|
866
|
+
const sly = createClient();
|
|
867
|
+
const result = await sly.a2a.cancelTask(opts.agentId, opts.taskId);
|
|
868
|
+
output(result);
|
|
869
|
+
} catch (e) {
|
|
870
|
+
error(e.message);
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// src/commands/agent-wallets.ts
|
|
876
|
+
function registerAgentWalletsCommands(program2) {
|
|
877
|
+
const cmd = program2.command("agent-wallets").description("Agent wallet policies, exposures, and governance");
|
|
878
|
+
cmd.command("get <agentId>").description("Get agent wallet details including balance and spending policy").action(async (agentId) => {
|
|
879
|
+
try {
|
|
880
|
+
const sly = createClient();
|
|
881
|
+
const result = await sly.agentWallets.getWallet(agentId);
|
|
882
|
+
output(result);
|
|
883
|
+
} catch (e) {
|
|
884
|
+
error(e.message);
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
cmd.command("evaluate-policy <agentId>").description("Evaluate contract policy for an agent payment (dry-run)").requiredOption("--amount <amount>", "Payment amount to evaluate", parseFloat).option("--currency <currency>", "Currency (default: USDC)").option("--action-type <type>", "Action type (payment, escrow_create, escrow_release, contract_sign, negotiation_check, counterparty_check)").option("--contract-type <type>", "Contract type").option("--counterparty-agent-id <id>", "UUID of the counterparty agent").option("--counterparty-address <addr>", "Wallet address of external counterparty").action(async (agentId, opts) => {
|
|
888
|
+
try {
|
|
889
|
+
const sly = createClient();
|
|
890
|
+
const result = await sly.agentWallets.evaluatePolicy(agentId, {
|
|
891
|
+
amount: opts.amount,
|
|
892
|
+
currency: opts.currency,
|
|
893
|
+
actionType: opts.actionType || "negotiation_check",
|
|
894
|
+
contractType: opts.contractType,
|
|
895
|
+
counterpartyAgentId: opts.counterpartyAgentId,
|
|
896
|
+
counterpartyAddress: opts.counterpartyAddress
|
|
897
|
+
});
|
|
898
|
+
output(result);
|
|
899
|
+
} catch (e) {
|
|
900
|
+
error(e.message);
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
cmd.command("exposures <agentId>").description("List per-counterparty exposure windows for an agent wallet").action(async (agentId) => {
|
|
904
|
+
try {
|
|
905
|
+
const sly = createClient();
|
|
906
|
+
const result = await sly.agentWallets.getExposures(agentId);
|
|
907
|
+
output(result);
|
|
908
|
+
} catch (e) {
|
|
909
|
+
error(e.message);
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
cmd.command("evaluations <agentId>").description("Get the policy evaluation audit log for an agent wallet").option("--page <page>", "Page number", parseInt).option("--limit <limit>", "Results per page", parseInt).action(async (agentId, opts) => {
|
|
913
|
+
try {
|
|
914
|
+
const sly = createClient();
|
|
915
|
+
const result = await sly.agentWallets.getEvaluations(agentId, {
|
|
916
|
+
page: opts.page,
|
|
917
|
+
limit: opts.limit
|
|
918
|
+
});
|
|
919
|
+
output(result);
|
|
920
|
+
} catch (e) {
|
|
921
|
+
error(e.message);
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
cmd.command("freeze <agentId>").description("Freeze an agent's wallet (disables all payments)").action(async (agentId) => {
|
|
925
|
+
try {
|
|
926
|
+
const sly = createClient();
|
|
927
|
+
const result = await sly.agentWallets.freezeWallet(agentId);
|
|
928
|
+
output(result);
|
|
929
|
+
} catch (e) {
|
|
930
|
+
error(e.message);
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
cmd.command("unfreeze <agentId>").description("Unfreeze an agent's wallet").action(async (agentId) => {
|
|
934
|
+
try {
|
|
935
|
+
const sly = createClient();
|
|
936
|
+
const result = await sly.agentWallets.unfreezeWallet(agentId);
|
|
937
|
+
output(result);
|
|
938
|
+
} catch (e) {
|
|
939
|
+
error(e.message);
|
|
940
|
+
}
|
|
941
|
+
});
|
|
942
|
+
cmd.command("set-policy <agentId>").description("Set or update the spending and contract policy on an agent's wallet").option("--daily-spend-limit <amount>", "Daily spending limit", parseFloat).option("--monthly-spend-limit <amount>", "Monthly spending limit", parseFloat).option("--requires-approval-above <amount>", "Amount above which human approval is required", parseFloat).option("--approved-vendors <json>", "Approved vendor domains as JSON array").option("--contract-policy <json>", "Contract policy rules as JSON object").action(async (agentId, opts) => {
|
|
943
|
+
try {
|
|
944
|
+
const sly = createClient();
|
|
945
|
+
const policy = {};
|
|
946
|
+
if (opts.dailySpendLimit !== void 0) policy.dailySpendLimit = opts.dailySpendLimit;
|
|
947
|
+
if (opts.monthlySpendLimit !== void 0) policy.monthlySpendLimit = opts.monthlySpendLimit;
|
|
948
|
+
if (opts.requiresApprovalAbove !== void 0) policy.requiresApprovalAbove = opts.requiresApprovalAbove;
|
|
949
|
+
if (opts.approvedVendors) policy.approvedVendors = JSON.parse(opts.approvedVendors);
|
|
950
|
+
if (opts.contractPolicy) policy.contractPolicy = JSON.parse(opts.contractPolicy);
|
|
951
|
+
const result = await sly.agentWallets.setContractPolicy(agentId, policy);
|
|
952
|
+
output(result);
|
|
953
|
+
} catch (e) {
|
|
954
|
+
error(e.message);
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
// src/commands/merchants.ts
|
|
960
|
+
function registerMerchantsCommands(program2) {
|
|
961
|
+
const cmd = program2.command("merchants").description("Browse merchant catalogs");
|
|
962
|
+
cmd.command("list").description("List merchants with product catalogs").option("--type <type>", "Merchant type filter (e.g., restaurant, bar, hotel, retail)").option("--country <country>", "Country code filter (e.g., PA, CR)").option("--search <search>", "Search merchants by name").option("--limit <limit>", "Max results (default 50, max 100)", parseInt).action(async (opts) => {
|
|
963
|
+
try {
|
|
964
|
+
const sly = createClient();
|
|
965
|
+
const params = new URLSearchParams();
|
|
966
|
+
if (opts.type) params.set("type", opts.type);
|
|
967
|
+
if (opts.country) params.set("country", opts.country);
|
|
968
|
+
if (opts.search) params.set("search", opts.search);
|
|
969
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
970
|
+
const qs = params.toString();
|
|
971
|
+
const result = await sly.request(`/v1/ucp/merchants${qs ? `?${qs}` : ""}`);
|
|
972
|
+
output(result);
|
|
973
|
+
} catch (e) {
|
|
974
|
+
error(e.message);
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
cmd.command("get <merchantId>").description("Get a merchant's full product catalog").action(async (merchantId) => {
|
|
978
|
+
try {
|
|
979
|
+
const sly = createClient();
|
|
980
|
+
const result = await sly.request(`/v1/ucp/merchants/${merchantId}`);
|
|
981
|
+
output(result);
|
|
982
|
+
} catch (e) {
|
|
983
|
+
error(e.message);
|
|
984
|
+
}
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// src/commands/support.ts
|
|
989
|
+
function registerSupportCommands(program2) {
|
|
990
|
+
const cmd = program2.command("support").description("Support and dispute management");
|
|
991
|
+
cmd.command("explain-rejection").description("Explain why a transaction was rejected").option("--error-code <code>", "Error code from the rejection").option("--transaction-id <id>", "UUID of the rejected transaction").option("--agent-id <id>", "UUID of the agent").action(async (opts) => {
|
|
992
|
+
try {
|
|
993
|
+
const sly = createClient();
|
|
994
|
+
const body = {};
|
|
995
|
+
if (opts.errorCode) body.error_code = opts.errorCode;
|
|
996
|
+
if (opts.transactionId) body.transaction_id = opts.transactionId;
|
|
997
|
+
if (opts.agentId) body.agent_id = opts.agentId;
|
|
998
|
+
const result = await sly.request("/v1/support/explain-rejection", {
|
|
999
|
+
method: "POST",
|
|
1000
|
+
body: JSON.stringify(body)
|
|
1001
|
+
});
|
|
1002
|
+
output(result);
|
|
1003
|
+
} catch (e) {
|
|
1004
|
+
error(e.message);
|
|
1005
|
+
}
|
|
1006
|
+
});
|
|
1007
|
+
cmd.command("request-limit-increase").description("Submit a request to increase an agent's spending limit").requiredOption("--agent-id <agentId>", "UUID of the agent").requiredOption("--limit-type <type>", "Which limit to increase (per_transaction, daily, monthly)").requiredOption("--requested-amount <amount>", "The new desired limit amount (USD)", parseFloat).requiredOption("--reason <reason>", "Business justification").option("--duration <duration>", "How long the increase should last (temporary_24h, temporary_7d, permanent)").action(async (opts) => {
|
|
1008
|
+
try {
|
|
1009
|
+
const sly = createClient();
|
|
1010
|
+
const body = {
|
|
1011
|
+
agent_id: opts.agentId,
|
|
1012
|
+
limit_type: opts.limitType,
|
|
1013
|
+
requested_amount: opts.requestedAmount,
|
|
1014
|
+
reason: opts.reason
|
|
1015
|
+
};
|
|
1016
|
+
if (opts.duration) body.duration = opts.duration;
|
|
1017
|
+
const result = await sly.request("/v1/support/request-limit-increase", {
|
|
1018
|
+
method: "POST",
|
|
1019
|
+
body: JSON.stringify(body)
|
|
1020
|
+
});
|
|
1021
|
+
output(result);
|
|
1022
|
+
} catch (e) {
|
|
1023
|
+
error(e.message);
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
cmd.command("open-dispute").description("Open a dispute for a completed transaction").requiredOption("--transaction-id <id>", "UUID of the transaction").requiredOption("--reason <reason>", "Reason (service_not_received, duplicate_charge, unauthorized, amount_incorrect, quality_issue, other)").requiredOption("--description <description>", "Detailed description of the issue").option("--requested-resolution <resolution>", "Requested resolution (full_refund, partial_refund, credit, other)").action(async (opts) => {
|
|
1027
|
+
try {
|
|
1028
|
+
const sly = createClient();
|
|
1029
|
+
const body = {
|
|
1030
|
+
transaction_id: opts.transactionId,
|
|
1031
|
+
reason: opts.reason,
|
|
1032
|
+
description: opts.description
|
|
1033
|
+
};
|
|
1034
|
+
if (opts.requestedResolution) body.requested_resolution = opts.requestedResolution;
|
|
1035
|
+
const result = await sly.request("/v1/support/open-dispute", {
|
|
1036
|
+
method: "POST",
|
|
1037
|
+
body: JSON.stringify(body)
|
|
1038
|
+
});
|
|
1039
|
+
output(result);
|
|
1040
|
+
} catch (e) {
|
|
1041
|
+
error(e.message);
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
cmd.command("escalate").description("Escalate an issue to a human support operator").requiredOption("--reason <reason>", "Why this is being escalated (complex_issue, agent_requested, security_concern, policy_exception, bug_report)").requiredOption("--summary <summary>", "Summary of the issue").option("--agent-id <agentId>", "UUID of the agent").option("--priority <priority>", "Priority level (low, medium, high, critical)").action(async (opts) => {
|
|
1045
|
+
try {
|
|
1046
|
+
const sly = createClient();
|
|
1047
|
+
const body = {
|
|
1048
|
+
reason: opts.reason,
|
|
1049
|
+
summary: opts.summary
|
|
1050
|
+
};
|
|
1051
|
+
if (opts.agentId) body.agent_id = opts.agentId;
|
|
1052
|
+
if (opts.priority) body.priority = opts.priority;
|
|
1053
|
+
const result = await sly.request("/v1/support/escalate", {
|
|
1054
|
+
method: "POST",
|
|
1055
|
+
body: JSON.stringify(body)
|
|
1056
|
+
});
|
|
1057
|
+
output(result);
|
|
1058
|
+
} catch (e) {
|
|
1059
|
+
error(e.message);
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
// src/commands/env.ts
|
|
1065
|
+
function registerEnvCommands(program2) {
|
|
1066
|
+
const cmd = program2.command("env").description("Environment management");
|
|
1067
|
+
cmd.command("get").description("Show current environment info").action(() => {
|
|
1068
|
+
try {
|
|
1069
|
+
const apiKey = process.env.SLY_API_KEY;
|
|
1070
|
+
if (!apiKey) {
|
|
1071
|
+
error("SLY_API_KEY environment variable is not set");
|
|
1072
|
+
}
|
|
1073
|
+
const environment = apiKey.startsWith("pk_live_") ? "production" : "sandbox";
|
|
1074
|
+
const masked = apiKey.slice(0, 12) + "***";
|
|
1075
|
+
output({
|
|
1076
|
+
environment,
|
|
1077
|
+
apiKeyPrefix: masked,
|
|
1078
|
+
apiUrl: process.env.SLY_API_URL || (environment === "production" ? "https://api.getsly.ai" : "https://sandbox.getsly.ai")
|
|
1079
|
+
});
|
|
1080
|
+
} catch (e) {
|
|
1081
|
+
error(e.message);
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
cmd.command("switch <environment>").description("Show instructions for switching between sandbox and production").action((environment) => {
|
|
1085
|
+
if (environment !== "sandbox" && environment !== "production") {
|
|
1086
|
+
error('Environment must be "sandbox" or "production"');
|
|
1087
|
+
}
|
|
1088
|
+
const prefix = environment === "production" ? "pk_live_" : "pk_test_";
|
|
1089
|
+
console.log(`To switch to ${environment}, set your API key:`);
|
|
1090
|
+
console.log(` export SLY_API_KEY=${prefix}your_key_here`);
|
|
1091
|
+
if (environment === "production") {
|
|
1092
|
+
console.log(` export SLY_API_URL=https://api.getsly.ai`);
|
|
1093
|
+
} else {
|
|
1094
|
+
console.log(` export SLY_API_URL=https://sandbox.getsly.ai`);
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
cmd.command("whoami").description("Get information about the current tenant/organization").action(async () => {
|
|
1098
|
+
try {
|
|
1099
|
+
const apiKey = process.env.SLY_API_KEY;
|
|
1100
|
+
if (!apiKey) {
|
|
1101
|
+
error("SLY_API_KEY environment variable is not set");
|
|
1102
|
+
}
|
|
1103
|
+
const { createClient: createClient2 } = await import("./auth-ET55P6PZ.js");
|
|
1104
|
+
const sly = createClient2();
|
|
1105
|
+
const result = await sly.request("/v1/context/whoami");
|
|
1106
|
+
output(result);
|
|
1107
|
+
} catch (e) {
|
|
1108
|
+
error(e.message);
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
// src/index.ts
|
|
1114
|
+
var program = new Command().name("sly").description("Sly CLI \u2014 the agentic economy platform").version("0.1.0");
|
|
1115
|
+
registerAccountsCommands(program);
|
|
1116
|
+
registerAgentsCommands(program);
|
|
1117
|
+
registerWalletsCommands(program);
|
|
1118
|
+
registerSettlementCommands(program);
|
|
1119
|
+
registerX402Commands(program);
|
|
1120
|
+
registerAP2Commands(program);
|
|
1121
|
+
registerACPCommands(program);
|
|
1122
|
+
registerUCPCommands(program);
|
|
1123
|
+
registerMPPCommands(program);
|
|
1124
|
+
registerA2ACommands(program);
|
|
1125
|
+
registerAgentWalletsCommands(program);
|
|
1126
|
+
registerMerchantsCommands(program);
|
|
1127
|
+
registerSupportCommands(program);
|
|
1128
|
+
registerEnvCommands(program);
|
|
1129
|
+
program.parse();
|