@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
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createClient } from '../utils/auth.js';
|
|
3
|
+
import { output, error } from '../utils/output.js';
|
|
4
|
+
|
|
5
|
+
export function registerUCPCommands(program: Command) {
|
|
6
|
+
const cmd = program.command('ucp').description('UCP (Universal Commerce Protocol) operations');
|
|
7
|
+
|
|
8
|
+
cmd
|
|
9
|
+
.command('discover <merchantUrl>')
|
|
10
|
+
.description('Discover a UCP merchant\'s capabilities')
|
|
11
|
+
.action(async (merchantUrl) => {
|
|
12
|
+
try {
|
|
13
|
+
const sly = createClient();
|
|
14
|
+
const result = await sly.request('/v1/ucp/discover', {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
body: JSON.stringify({ merchantUrl }),
|
|
17
|
+
});
|
|
18
|
+
output(result);
|
|
19
|
+
} catch (e: unknown) {
|
|
20
|
+
error((e as Error).message);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
cmd
|
|
25
|
+
.command('checkouts')
|
|
26
|
+
.description('List UCP checkout sessions')
|
|
27
|
+
.option('--status <status>', 'Filter by status')
|
|
28
|
+
.option('--agent-id <agentId>', 'Filter by agent ID')
|
|
29
|
+
.option('--page <page>', 'Page number', parseInt)
|
|
30
|
+
.option('--limit <limit>', 'Results per page', parseInt)
|
|
31
|
+
.action(async (opts) => {
|
|
32
|
+
try {
|
|
33
|
+
const sly = createClient();
|
|
34
|
+
const params = new URLSearchParams();
|
|
35
|
+
if (opts.status) params.set('status', opts.status);
|
|
36
|
+
if (opts.agentId) params.set('agent_id', opts.agentId);
|
|
37
|
+
if (opts.page) params.set('page', String(opts.page));
|
|
38
|
+
if (opts.limit) params.set('limit', String(opts.limit));
|
|
39
|
+
const qs = params.toString();
|
|
40
|
+
const result = await sly.request(`/v1/ucp/checkouts${qs ? `?${qs}` : ''}`);
|
|
41
|
+
output(result);
|
|
42
|
+
} catch (e: unknown) {
|
|
43
|
+
error((e as Error).message);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
cmd
|
|
48
|
+
.command('create-checkout')
|
|
49
|
+
.description('Create a UCP checkout session')
|
|
50
|
+
.requiredOption('--currency <currency>', 'ISO 4217 pricing currency (e.g., USD)')
|
|
51
|
+
.requiredOption('--line-items <json>', 'Line items as JSON array')
|
|
52
|
+
.option('--buyer <json>', 'Buyer info as JSON')
|
|
53
|
+
.option('--shipping-address <json>', 'Shipping address as JSON')
|
|
54
|
+
.option('--checkout-type <type>', 'Checkout type (physical, digital, service)')
|
|
55
|
+
.option('--agent-id <agentId>', 'Agent ID to attribute this checkout to')
|
|
56
|
+
.option('--metadata <json>', 'Custom metadata as JSON')
|
|
57
|
+
.action(async (opts) => {
|
|
58
|
+
try {
|
|
59
|
+
const sly = createClient();
|
|
60
|
+
const body: Record<string, unknown> = {
|
|
61
|
+
currency: opts.currency,
|
|
62
|
+
line_items: JSON.parse(opts.lineItems),
|
|
63
|
+
};
|
|
64
|
+
if (opts.buyer) body.buyer = JSON.parse(opts.buyer);
|
|
65
|
+
if (opts.shippingAddress) body.shipping_address = JSON.parse(opts.shippingAddress);
|
|
66
|
+
if (opts.checkoutType) body.checkout_type = opts.checkoutType;
|
|
67
|
+
if (opts.agentId) body.agent_id = opts.agentId;
|
|
68
|
+
if (opts.metadata) body.metadata = JSON.parse(opts.metadata);
|
|
69
|
+
const result = await sly.request('/v1/ucp/checkouts', {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
body: JSON.stringify(body),
|
|
72
|
+
});
|
|
73
|
+
output(result);
|
|
74
|
+
} catch (e: unknown) {
|
|
75
|
+
error((e as Error).message);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
cmd
|
|
80
|
+
.command('get-checkout <id>')
|
|
81
|
+
.description('Get UCP checkout details')
|
|
82
|
+
.action(async (id) => {
|
|
83
|
+
try {
|
|
84
|
+
const sly = createClient();
|
|
85
|
+
const result = await sly.request(`/v1/ucp/checkouts/${id}`);
|
|
86
|
+
output(result);
|
|
87
|
+
} catch (e: unknown) {
|
|
88
|
+
error((e as Error).message);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
cmd
|
|
93
|
+
.command('complete-checkout <id>')
|
|
94
|
+
.description('Complete a UCP checkout')
|
|
95
|
+
.action(async (id) => {
|
|
96
|
+
try {
|
|
97
|
+
const sly = createClient();
|
|
98
|
+
const result = await sly.request(`/v1/ucp/checkouts/${id}/complete`, {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
});
|
|
101
|
+
output(result);
|
|
102
|
+
} catch (e: unknown) {
|
|
103
|
+
error((e as Error).message);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
cmd
|
|
108
|
+
.command('cancel-checkout <id>')
|
|
109
|
+
.description('Cancel a UCP checkout session')
|
|
110
|
+
.action(async (id) => {
|
|
111
|
+
try {
|
|
112
|
+
const sly = createClient();
|
|
113
|
+
const result = await sly.request(`/v1/ucp/checkouts/${id}/cancel`, {
|
|
114
|
+
method: 'POST',
|
|
115
|
+
});
|
|
116
|
+
output(result);
|
|
117
|
+
} catch (e: unknown) {
|
|
118
|
+
error((e as Error).message);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
cmd
|
|
123
|
+
.command('add-instrument <checkoutId>')
|
|
124
|
+
.description('Add a payment instrument to a UCP checkout')
|
|
125
|
+
.requiredOption('--instrument-id <id>', 'Unique instrument identifier')
|
|
126
|
+
.requiredOption('--handler <handler>', 'Payment handler (e.g., sly)')
|
|
127
|
+
.requiredOption('--type <type>', 'Instrument type (e.g., usdc)')
|
|
128
|
+
.option('--last4 <last4>', 'Last 4 digits')
|
|
129
|
+
.option('--brand <brand>', 'Brand name')
|
|
130
|
+
.action(async (checkoutId, opts) => {
|
|
131
|
+
try {
|
|
132
|
+
const sly = createClient();
|
|
133
|
+
const body: Record<string, unknown> = {
|
|
134
|
+
id: opts.instrumentId,
|
|
135
|
+
handler: opts.handler,
|
|
136
|
+
type: opts.type,
|
|
137
|
+
};
|
|
138
|
+
if (opts.last4) body.last4 = opts.last4;
|
|
139
|
+
if (opts.brand) body.brand = opts.brand;
|
|
140
|
+
const result = await sly.request(`/v1/ucp/checkouts/${checkoutId}/instruments`, {
|
|
141
|
+
method: 'POST',
|
|
142
|
+
body: JSON.stringify(body),
|
|
143
|
+
});
|
|
144
|
+
output(result);
|
|
145
|
+
} catch (e: unknown) {
|
|
146
|
+
error((e as Error).message);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
cmd
|
|
151
|
+
.command('orders')
|
|
152
|
+
.description('List UCP orders')
|
|
153
|
+
.option('--status <status>', 'Filter by order status')
|
|
154
|
+
.option('--agent-id <agentId>', 'Filter by agent ID')
|
|
155
|
+
.option('--page <page>', 'Page number', parseInt)
|
|
156
|
+
.option('--limit <limit>', 'Results per page', parseInt)
|
|
157
|
+
.action(async (opts) => {
|
|
158
|
+
try {
|
|
159
|
+
const sly = createClient();
|
|
160
|
+
const params = new URLSearchParams();
|
|
161
|
+
if (opts.status) params.set('status', opts.status);
|
|
162
|
+
if (opts.agentId) params.set('agent_id', opts.agentId);
|
|
163
|
+
if (opts.page) params.set('page', String(opts.page));
|
|
164
|
+
if (opts.limit) params.set('limit', String(opts.limit));
|
|
165
|
+
const qs = params.toString();
|
|
166
|
+
const result = await sly.request(`/v1/ucp/orders${qs ? `?${qs}` : ''}`);
|
|
167
|
+
output(result);
|
|
168
|
+
} catch (e: unknown) {
|
|
169
|
+
error((e as Error).message);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
cmd
|
|
174
|
+
.command('get-order <id>')
|
|
175
|
+
.description('Get UCP order details')
|
|
176
|
+
.action(async (id) => {
|
|
177
|
+
try {
|
|
178
|
+
const sly = createClient();
|
|
179
|
+
const result = await sly.request(`/v1/ucp/orders/${id}`);
|
|
180
|
+
output(result);
|
|
181
|
+
} catch (e: unknown) {
|
|
182
|
+
error((e as Error).message);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
cmd
|
|
187
|
+
.command('update-order-status <orderId>')
|
|
188
|
+
.description('Update UCP order status')
|
|
189
|
+
.requiredOption('--status <status>', 'New order status (processing, shipped, delivered)')
|
|
190
|
+
.action(async (orderId, opts) => {
|
|
191
|
+
try {
|
|
192
|
+
const sly = createClient();
|
|
193
|
+
const result = await sly.request(`/v1/ucp/orders/${orderId}/status`, {
|
|
194
|
+
method: 'PUT',
|
|
195
|
+
body: JSON.stringify({ status: opts.status }),
|
|
196
|
+
});
|
|
197
|
+
output(result);
|
|
198
|
+
} catch (e: unknown) {
|
|
199
|
+
error((e as Error).message);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
cmd
|
|
204
|
+
.command('cancel-order <orderId>')
|
|
205
|
+
.description('Cancel a UCP order')
|
|
206
|
+
.option('--reason <reason>', 'Cancellation reason')
|
|
207
|
+
.action(async (orderId, opts) => {
|
|
208
|
+
try {
|
|
209
|
+
const sly = createClient();
|
|
210
|
+
const result = await sly.request(`/v1/ucp/orders/${orderId}/cancel`, {
|
|
211
|
+
method: 'POST',
|
|
212
|
+
body: JSON.stringify({ reason: opts.reason }),
|
|
213
|
+
});
|
|
214
|
+
output(result);
|
|
215
|
+
} catch (e: unknown) {
|
|
216
|
+
error((e as Error).message);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
cmd
|
|
221
|
+
.command('add-event <orderId>')
|
|
222
|
+
.description('Record a fulfillment event on a UCP order')
|
|
223
|
+
.requiredOption('--type <type>', 'Event type (shipped, in_transit, out_for_delivery, delivered, returned)')
|
|
224
|
+
.requiredOption('--description <description>', 'Event description')
|
|
225
|
+
.option('--tracking-number <trackingNumber>', 'Tracking number')
|
|
226
|
+
.option('--carrier <carrier>', 'Shipping carrier')
|
|
227
|
+
.action(async (orderId, opts) => {
|
|
228
|
+
try {
|
|
229
|
+
const sly = createClient();
|
|
230
|
+
const body: Record<string, unknown> = {
|
|
231
|
+
type: opts.type,
|
|
232
|
+
description: opts.description,
|
|
233
|
+
};
|
|
234
|
+
if (opts.trackingNumber) body.tracking_number = opts.trackingNumber;
|
|
235
|
+
if (opts.carrier) body.carrier = opts.carrier;
|
|
236
|
+
const result = await sly.request(`/v1/ucp/orders/${orderId}/events`, {
|
|
237
|
+
method: 'POST',
|
|
238
|
+
body: JSON.stringify(body),
|
|
239
|
+
});
|
|
240
|
+
output(result);
|
|
241
|
+
} catch (e: unknown) {
|
|
242
|
+
error((e as Error).message);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createClient } from '../utils/auth.js';
|
|
3
|
+
import { output, error } from '../utils/output.js';
|
|
4
|
+
|
|
5
|
+
export function registerWalletsCommands(program: Command) {
|
|
6
|
+
const cmd = program.command('wallets').description('Manage wallets');
|
|
7
|
+
|
|
8
|
+
cmd
|
|
9
|
+
.command('list')
|
|
10
|
+
.description('List wallets')
|
|
11
|
+
.option('--status <status>', 'Filter by status (active, frozen, depleted)')
|
|
12
|
+
.option('--owner-account-id <id>', 'Filter by owner account UUID')
|
|
13
|
+
.option('--managed-by-agent-id <id>', 'Filter by managing agent UUID')
|
|
14
|
+
.option('--page <page>', 'Page number', parseInt)
|
|
15
|
+
.option('--limit <limit>', 'Results per page', parseInt)
|
|
16
|
+
.action(async (opts) => {
|
|
17
|
+
try {
|
|
18
|
+
const sly = createClient();
|
|
19
|
+
const params = new URLSearchParams();
|
|
20
|
+
if (opts.status) params.set('status', opts.status);
|
|
21
|
+
if (opts.ownerAccountId) params.set('owner_account_id', opts.ownerAccountId);
|
|
22
|
+
if (opts.managedByAgentId) params.set('managed_by_agent_id', opts.managedByAgentId);
|
|
23
|
+
if (opts.page) params.set('page', String(opts.page));
|
|
24
|
+
if (opts.limit) params.set('limit', String(opts.limit));
|
|
25
|
+
const qs = params.toString();
|
|
26
|
+
const result = await sly.request(`/v1/wallets${qs ? `?${qs}` : ''}`);
|
|
27
|
+
output(result);
|
|
28
|
+
} catch (e: unknown) {
|
|
29
|
+
error((e as Error).message);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
cmd
|
|
34
|
+
.command('create')
|
|
35
|
+
.description('Create a new wallet for an account')
|
|
36
|
+
.requiredOption('--account-id <accountId>', 'UUID of the owning account')
|
|
37
|
+
.option('--name <name>', 'Human-readable wallet name')
|
|
38
|
+
.option('--blockchain <blockchain>', 'Blockchain network (base, eth, polygon, avax, sol)')
|
|
39
|
+
.option('--wallet-type <walletType>', 'Wallet type (internal, circle_custodial, circle_mpc)')
|
|
40
|
+
.option('--currency <currency>', 'Wallet currency (USDC, EURC)')
|
|
41
|
+
.option('--managed-by-agent-id <agentId>', 'UUID of managing agent')
|
|
42
|
+
.option('--purpose <purpose>', 'Purpose of the wallet')
|
|
43
|
+
.action(async (opts) => {
|
|
44
|
+
try {
|
|
45
|
+
const sly = createClient();
|
|
46
|
+
const body: Record<string, unknown> = { accountId: opts.accountId };
|
|
47
|
+
if (opts.name) body.name = opts.name;
|
|
48
|
+
if (opts.blockchain) body.blockchain = opts.blockchain;
|
|
49
|
+
if (opts.walletType) body.walletType = opts.walletType;
|
|
50
|
+
if (opts.currency) body.currency = opts.currency;
|
|
51
|
+
if (opts.managedByAgentId) body.managedByAgentId = opts.managedByAgentId;
|
|
52
|
+
if (opts.purpose) body.purpose = opts.purpose;
|
|
53
|
+
const result = await sly.request('/v1/wallets', {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
body: JSON.stringify(body),
|
|
56
|
+
});
|
|
57
|
+
output(result);
|
|
58
|
+
} catch (e: unknown) {
|
|
59
|
+
error((e as Error).message);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
cmd
|
|
64
|
+
.command('get <id>')
|
|
65
|
+
.description('Get wallet details')
|
|
66
|
+
.action(async (id) => {
|
|
67
|
+
try {
|
|
68
|
+
const sly = createClient();
|
|
69
|
+
const result = await sly.request(`/v1/wallets/${id}`);
|
|
70
|
+
output(result);
|
|
71
|
+
} catch (e: unknown) {
|
|
72
|
+
error((e as Error).message);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
cmd
|
|
77
|
+
.command('balance <id>')
|
|
78
|
+
.description('Get wallet balance')
|
|
79
|
+
.action(async (id) => {
|
|
80
|
+
try {
|
|
81
|
+
const sly = createClient();
|
|
82
|
+
const result = await sly.request(`/v1/wallets/${id}/balance`);
|
|
83
|
+
output(result);
|
|
84
|
+
} catch (e: unknown) {
|
|
85
|
+
error((e as Error).message);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
cmd
|
|
90
|
+
.command('fund <id>')
|
|
91
|
+
.description('Add test funds to a wallet (sandbox only)')
|
|
92
|
+
.requiredOption('--amount <amount>', 'Amount of test funds to add', parseFloat)
|
|
93
|
+
.option('--currency <currency>', 'Currency (USDC, EURC)')
|
|
94
|
+
.option('--reference <reference>', 'Reference note')
|
|
95
|
+
.action(async (id, opts) => {
|
|
96
|
+
try {
|
|
97
|
+
const sly = createClient();
|
|
98
|
+
const body: Record<string, unknown> = { amount: opts.amount };
|
|
99
|
+
if (opts.currency) body.currency = opts.currency;
|
|
100
|
+
if (opts.reference) body.reference = opts.reference;
|
|
101
|
+
const result = await sly.request(`/v1/wallets/${id}/test-fund`, {
|
|
102
|
+
method: 'POST',
|
|
103
|
+
body: JSON.stringify(body),
|
|
104
|
+
});
|
|
105
|
+
output(result);
|
|
106
|
+
} catch (e: unknown) {
|
|
107
|
+
error((e as Error).message);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
cmd
|
|
112
|
+
.command('deposit <id>')
|
|
113
|
+
.description('Deposit funds into a wallet')
|
|
114
|
+
.requiredOption('--amount <amount>', 'Amount to deposit', parseFloat)
|
|
115
|
+
.requiredOption('--from-account-id <accountId>', 'UUID of the source account')
|
|
116
|
+
.option('--reference <reference>', 'Reference note')
|
|
117
|
+
.action(async (id, opts) => {
|
|
118
|
+
try {
|
|
119
|
+
const sly = createClient();
|
|
120
|
+
const body: Record<string, unknown> = {
|
|
121
|
+
amount: opts.amount,
|
|
122
|
+
fromAccountId: opts.fromAccountId,
|
|
123
|
+
};
|
|
124
|
+
if (opts.reference) body.reference = opts.reference;
|
|
125
|
+
const result = await sly.request(`/v1/wallets/${id}/deposit`, {
|
|
126
|
+
method: 'POST',
|
|
127
|
+
body: JSON.stringify(body),
|
|
128
|
+
});
|
|
129
|
+
output(result);
|
|
130
|
+
} catch (e: unknown) {
|
|
131
|
+
error((e as Error).message);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
cmd
|
|
136
|
+
.command('withdraw <id>')
|
|
137
|
+
.description('Withdraw funds from a wallet')
|
|
138
|
+
.requiredOption('--amount <amount>', 'Amount to withdraw', parseFloat)
|
|
139
|
+
.requiredOption('--destination-account-id <accountId>', 'UUID of the destination account')
|
|
140
|
+
.option('--reference <reference>', 'Reference note')
|
|
141
|
+
.action(async (id, opts) => {
|
|
142
|
+
try {
|
|
143
|
+
const sly = createClient();
|
|
144
|
+
const body: Record<string, unknown> = {
|
|
145
|
+
amount: opts.amount,
|
|
146
|
+
destinationAccountId: opts.destinationAccountId,
|
|
147
|
+
};
|
|
148
|
+
if (opts.reference) body.reference = opts.reference;
|
|
149
|
+
const result = await sly.request(`/v1/wallets/${id}/withdraw`, {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
body: JSON.stringify(body),
|
|
152
|
+
});
|
|
153
|
+
output(result);
|
|
154
|
+
} catch (e: unknown) {
|
|
155
|
+
error((e as Error).message);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createClient } from '../utils/auth.js';
|
|
3
|
+
import { output, error } from '../utils/output.js';
|
|
4
|
+
|
|
5
|
+
export function registerX402Commands(program: Command) {
|
|
6
|
+
const cmd = program.command('x402').description('x402 micropayment endpoints');
|
|
7
|
+
|
|
8
|
+
cmd
|
|
9
|
+
.command('endpoints')
|
|
10
|
+
.description('List x402 payment endpoints')
|
|
11
|
+
.option('--status <status>', 'Filter by status (active, paused, disabled)')
|
|
12
|
+
.option('--account-id <id>', 'Filter by account UUID')
|
|
13
|
+
.option('--page <page>', 'Page number', parseInt)
|
|
14
|
+
.option('--limit <limit>', 'Results per page', parseInt)
|
|
15
|
+
.action(async (opts) => {
|
|
16
|
+
try {
|
|
17
|
+
const sly = createClient();
|
|
18
|
+
const params = new URLSearchParams();
|
|
19
|
+
if (opts.status) params.set('status', opts.status);
|
|
20
|
+
if (opts.accountId) params.set('account_id', opts.accountId);
|
|
21
|
+
if (opts.page) params.set('page', String(opts.page));
|
|
22
|
+
if (opts.limit) params.set('limit', String(opts.limit));
|
|
23
|
+
const qs = params.toString();
|
|
24
|
+
const result = await sly.request(`/v1/x402/endpoints${qs ? `?${qs}` : ''}`);
|
|
25
|
+
output(result);
|
|
26
|
+
} catch (e: unknown) {
|
|
27
|
+
error((e as Error).message);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
cmd
|
|
32
|
+
.command('get-endpoint <id>')
|
|
33
|
+
.description('Get x402 endpoint details')
|
|
34
|
+
.action(async (id) => {
|
|
35
|
+
try {
|
|
36
|
+
const sly = createClient();
|
|
37
|
+
const result = await sly.request(`/v1/x402/endpoints/${id}`);
|
|
38
|
+
output(result);
|
|
39
|
+
} catch (e: unknown) {
|
|
40
|
+
error((e as Error).message);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
cmd
|
|
45
|
+
.command('create-endpoint')
|
|
46
|
+
.description('Register an x402 payment endpoint')
|
|
47
|
+
.requiredOption('--name <name>', 'Endpoint name')
|
|
48
|
+
.requiredOption('--path <path>', 'API path (must start with /)')
|
|
49
|
+
.requiredOption('--method <method>', 'HTTP method (GET, POST, PUT, DELETE, PATCH, ANY)')
|
|
50
|
+
.requiredOption('--account-id <accountId>', 'UUID of the account receiving payments')
|
|
51
|
+
.requiredOption('--base-price <price>', 'Price per request in token units', parseFloat)
|
|
52
|
+
.option('--currency <currency>', 'Payment currency (USDC, EURC)')
|
|
53
|
+
.option('--description <description>', 'What this endpoint provides')
|
|
54
|
+
.option('--webhook-url <url>', 'URL to notify on payment')
|
|
55
|
+
.option('--network <network>', 'Blockchain network')
|
|
56
|
+
.action(async (opts) => {
|
|
57
|
+
try {
|
|
58
|
+
const sly = createClient();
|
|
59
|
+
const body: Record<string, unknown> = {
|
|
60
|
+
name: opts.name,
|
|
61
|
+
path: opts.path,
|
|
62
|
+
method: opts.method,
|
|
63
|
+
accountId: opts.accountId,
|
|
64
|
+
basePrice: opts.basePrice,
|
|
65
|
+
};
|
|
66
|
+
if (opts.currency) body.currency = opts.currency;
|
|
67
|
+
if (opts.description) body.description = opts.description;
|
|
68
|
+
if (opts.webhookUrl) body.webhookUrl = opts.webhookUrl;
|
|
69
|
+
if (opts.network) body.network = opts.network;
|
|
70
|
+
const result = await sly.request('/v1/x402/endpoints', {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
body: JSON.stringify(body),
|
|
73
|
+
});
|
|
74
|
+
output(result);
|
|
75
|
+
} catch (e: unknown) {
|
|
76
|
+
error((e as Error).message);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
cmd
|
|
81
|
+
.command('pay')
|
|
82
|
+
.description('Make an x402 micropayment to a paid endpoint')
|
|
83
|
+
.requiredOption('--endpoint-id <endpointId>', 'UUID of the x402 endpoint to pay')
|
|
84
|
+
.requiredOption('--wallet-id <walletId>', 'UUID of the wallet to pay from')
|
|
85
|
+
.requiredOption('--amount <amount>', 'Payment amount', parseFloat)
|
|
86
|
+
.requiredOption('--currency <currency>', 'Payment currency (USDC, EURC)')
|
|
87
|
+
.requiredOption('--method <method>', 'HTTP method of the request being paid for')
|
|
88
|
+
.requiredOption('--path <path>', 'Path of the request being paid for')
|
|
89
|
+
.action(async (opts) => {
|
|
90
|
+
try {
|
|
91
|
+
const sly = createClient();
|
|
92
|
+
const result = await sly.request('/v1/x402/payments', {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
body: JSON.stringify({
|
|
95
|
+
endpointId: opts.endpointId,
|
|
96
|
+
walletId: opts.walletId,
|
|
97
|
+
amount: opts.amount,
|
|
98
|
+
currency: opts.currency,
|
|
99
|
+
method: opts.method,
|
|
100
|
+
path: opts.path,
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
output(result);
|
|
104
|
+
} catch (e: unknown) {
|
|
105
|
+
error((e as Error).message);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
cmd
|
|
110
|
+
.command('verify')
|
|
111
|
+
.description('Verify an x402 payment')
|
|
112
|
+
.option('--jwt <jwt>', 'JWT payment proof for fast verification')
|
|
113
|
+
.option('--request-id <requestId>', 'Request ID for database verification')
|
|
114
|
+
.option('--transfer-id <transferId>', 'Transfer ID for database verification')
|
|
115
|
+
.action(async (opts) => {
|
|
116
|
+
try {
|
|
117
|
+
const sly = createClient();
|
|
118
|
+
const body: Record<string, unknown> = {};
|
|
119
|
+
if (opts.jwt) body.jwt = opts.jwt;
|
|
120
|
+
if (opts.requestId) body.requestId = opts.requestId;
|
|
121
|
+
if (opts.transferId) body.transferId = opts.transferId;
|
|
122
|
+
const result = await sly.request('/v1/x402/verify', {
|
|
123
|
+
method: 'POST',
|
|
124
|
+
body: JSON.stringify(body),
|
|
125
|
+
});
|
|
126
|
+
output(result);
|
|
127
|
+
} catch (e: unknown) {
|
|
128
|
+
error((e as Error).message);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { registerAccountsCommands } from './commands/accounts.js';
|
|
4
|
+
import { registerAgentsCommands } from './commands/agents.js';
|
|
5
|
+
import { registerWalletsCommands } from './commands/wallets.js';
|
|
6
|
+
import { registerSettlementCommands } from './commands/settlement.js';
|
|
7
|
+
import { registerX402Commands } from './commands/x402.js';
|
|
8
|
+
import { registerAP2Commands } from './commands/ap2.js';
|
|
9
|
+
import { registerACPCommands } from './commands/acp.js';
|
|
10
|
+
import { registerUCPCommands } from './commands/ucp.js';
|
|
11
|
+
import { registerMPPCommands } from './commands/mpp.js';
|
|
12
|
+
import { registerA2ACommands } from './commands/a2a.js';
|
|
13
|
+
import { registerAgentWalletsCommands } from './commands/agent-wallets.js';
|
|
14
|
+
import { registerMerchantsCommands } from './commands/merchants.js';
|
|
15
|
+
import { registerSupportCommands } from './commands/support.js';
|
|
16
|
+
import { registerEnvCommands } from './commands/env.js';
|
|
17
|
+
|
|
18
|
+
const program = new Command()
|
|
19
|
+
.name('sly')
|
|
20
|
+
.description('Sly CLI — the agentic economy platform')
|
|
21
|
+
.version('0.1.0');
|
|
22
|
+
|
|
23
|
+
registerAccountsCommands(program);
|
|
24
|
+
registerAgentsCommands(program);
|
|
25
|
+
registerWalletsCommands(program);
|
|
26
|
+
registerSettlementCommands(program);
|
|
27
|
+
registerX402Commands(program);
|
|
28
|
+
registerAP2Commands(program);
|
|
29
|
+
registerACPCommands(program);
|
|
30
|
+
registerUCPCommands(program);
|
|
31
|
+
registerMPPCommands(program);
|
|
32
|
+
registerA2ACommands(program);
|
|
33
|
+
registerAgentWalletsCommands(program);
|
|
34
|
+
registerMerchantsCommands(program);
|
|
35
|
+
registerSupportCommands(program);
|
|
36
|
+
registerEnvCommands(program);
|
|
37
|
+
|
|
38
|
+
program.parse();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Sly } from '@sly/sdk';
|
|
2
|
+
|
|
3
|
+
export function createClient(): Sly {
|
|
4
|
+
const apiKey = process.env.SLY_API_KEY;
|
|
5
|
+
if (!apiKey) {
|
|
6
|
+
console.error('Error: SLY_API_KEY environment variable is required');
|
|
7
|
+
console.error('Set it with: export SLY_API_KEY=pk_test_...');
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
return new Sly({
|
|
11
|
+
apiKey,
|
|
12
|
+
apiUrl: process.env.SLY_API_URL,
|
|
13
|
+
});
|
|
14
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2020"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"declarationMap": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"outDir": "./dist",
|
|
15
|
+
"rootDir": "./src",
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"allowSyntheticDefaultImports": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noImplicitReturns": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src/**/*"],
|
|
24
|
+
"exclude": ["node_modules", "dist"]
|
|
25
|
+
}
|