apinow-sdk 0.15.1 → 0.17.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/README.md +46 -0
- package/dist/cli.js +296 -1
- package/dist/index.d.ts +70 -0
- package/dist/index.js +119 -0
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -42,9 +42,30 @@ Returns:
|
|
|
42
42
|
| `call(endpoint, opts?)` | Call any endpoint with automatic x402 payment |
|
|
43
43
|
| `search(query, limit?)` | Semantic search across all endpoints |
|
|
44
44
|
| `info(ns, name)` | Get endpoint details (free) |
|
|
45
|
+
| `listWorkflows(opts?)` | List workflows (free) |
|
|
46
|
+
| `getWorkflow(id)` | Get workflow details (free) |
|
|
47
|
+
| `runWorkflow(id, input)` | Run a workflow with automatic x402 payment |
|
|
45
48
|
| `wallet` | Your wallet address |
|
|
46
49
|
| `fetch` | Raw x402-wrapped `fetch` for advanced use |
|
|
47
50
|
|
|
51
|
+
### Workflows
|
|
52
|
+
|
|
53
|
+
Workflows chain multiple x402 endpoints into a single paid DAG pipeline with automatic payment splitting.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
// list workflows
|
|
57
|
+
const { workflows } = await apinow.listWorkflows({ status: 'active', limit: 10 });
|
|
58
|
+
|
|
59
|
+
// get workflow details (nodes, splits, pricing)
|
|
60
|
+
const workflow = await apinow.getWorkflow('90931d9c8fb94df9');
|
|
61
|
+
console.log(workflow.name, workflow.totalPrice, workflow.graph.nodes);
|
|
62
|
+
|
|
63
|
+
// run a workflow — x402 payment covers all nodes + creator split
|
|
64
|
+
const result = await apinow.runWorkflow('90931d9c8fb94df9', {
|
|
65
|
+
query: 'birthday gift ideas for a friend who loves cooking',
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
48
69
|
## CLI
|
|
49
70
|
|
|
50
71
|
```bash
|
|
@@ -87,6 +108,31 @@ npx apinow call ns/endpoint -m GET -k 0xYOUR_KEY
|
|
|
87
108
|
| `-m, --method <method>` | HTTP method (default: from endpoint) |
|
|
88
109
|
| `-k, --key <privateKey>` | Wallet key (or set `APINOW_WALLET_PKEY`) |
|
|
89
110
|
|
|
111
|
+
### `workflows` — list workflows
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx apinow workflows
|
|
115
|
+
npx apinow workflows --status active --limit 10
|
|
116
|
+
npx apinow workflows --creator 0x32e8...E934
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### `workflow` — workflow details
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx apinow workflow 90931d9c8fb94df9
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `run-workflow` — run a workflow (paid)
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
APINOW_WALLET_PKEY=0x... npx apinow run-workflow 90931d9c8fb94df9 -d '{"query":"birthday gift ideas"}'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
| Flag | Description |
|
|
132
|
+
|------|-------------|
|
|
133
|
+
| `-d, --data <json>` | JSON input (default: `{"query":"hello world"}`) |
|
|
134
|
+
| `-k, --key <privateKey>` | Wallet key (or set `APINOW_WALLET_PKEY`) |
|
|
135
|
+
|
|
90
136
|
## Requirements
|
|
91
137
|
|
|
92
138
|
- Node.js v18+
|
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { createClient } from './index.js';
|
|
4
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
4
5
|
const API_BASE = 'https://apinow.fun';
|
|
5
6
|
const program = new Command();
|
|
6
7
|
program
|
|
7
8
|
.name('apinow')
|
|
8
9
|
.description('CLI for APINow.fun — search, inspect, and call pay-per-request APIs')
|
|
9
|
-
.version('0.
|
|
10
|
+
.version('0.17.0');
|
|
10
11
|
// ─── Helpers ───
|
|
11
12
|
function getPrivateKey(opts) {
|
|
12
13
|
const raw = opts.key || process.env.APINOW_WALLET_PKEY || process.env.PRIVATE_KEY;
|
|
@@ -42,6 +43,14 @@ function printTable(rows) {
|
|
|
42
43
|
function truncate(s, max) {
|
|
43
44
|
return s.length > max ? s.slice(0, max - 1) + '…' : s;
|
|
44
45
|
}
|
|
46
|
+
function getWallet(opts) {
|
|
47
|
+
const privateKey = getPrivateKey(opts);
|
|
48
|
+
const account = privateKeyToAccount(privateKey);
|
|
49
|
+
return { privateKey, address: account.address };
|
|
50
|
+
}
|
|
51
|
+
function walletHeaders(address) {
|
|
52
|
+
return { 'Content-Type': 'application/json', 'x-wallet-address': address };
|
|
53
|
+
}
|
|
45
54
|
// ─── search ───
|
|
46
55
|
program
|
|
47
56
|
.command('search <query>')
|
|
@@ -216,4 +225,290 @@ program
|
|
|
216
225
|
process.exit(1);
|
|
217
226
|
}
|
|
218
227
|
});
|
|
228
|
+
// ─── workflows ───
|
|
229
|
+
program
|
|
230
|
+
.command('workflows')
|
|
231
|
+
.description('List workflows')
|
|
232
|
+
.option('-l, --limit <n>', 'Max results', '20')
|
|
233
|
+
.option('-c, --creator <address>', 'Filter by creator wallet')
|
|
234
|
+
.option('-s, --status <status>', 'Filter by status: active | draft | all', 'all')
|
|
235
|
+
.action(async (opts) => {
|
|
236
|
+
try {
|
|
237
|
+
const params = new URLSearchParams({ limit: opts.limit, status: opts.status });
|
|
238
|
+
if (opts.creator)
|
|
239
|
+
params.set('creator', opts.creator);
|
|
240
|
+
const data = await fetchJson(`${API_BASE}/api/workflows?${params}`);
|
|
241
|
+
const workflows = data.workflows || [];
|
|
242
|
+
if (!workflows.length) {
|
|
243
|
+
console.log('No workflows found.');
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const rows = [['ID', 'NAME', 'STATUS', 'NODES', 'COST', 'DESCRIPTION']];
|
|
247
|
+
for (const w of workflows) {
|
|
248
|
+
rows.push([
|
|
249
|
+
w.workflowId,
|
|
250
|
+
truncate(w.name || '', 24),
|
|
251
|
+
w.status,
|
|
252
|
+
String(w.graph?.nodes?.length || 0),
|
|
253
|
+
`$${w.totalPrice}`,
|
|
254
|
+
truncate(w.description || '', 40),
|
|
255
|
+
]);
|
|
256
|
+
}
|
|
257
|
+
printTable(rows);
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
console.error(`Error: ${err.message}`);
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
// ─── workflow info ───
|
|
265
|
+
program
|
|
266
|
+
.command('workflow <id>')
|
|
267
|
+
.description('Get workflow details')
|
|
268
|
+
.action(async (id) => {
|
|
269
|
+
try {
|
|
270
|
+
const data = await fetchJson(`${API_BASE}/api/workflows/${id}`);
|
|
271
|
+
console.log(`\n ${data.name}`);
|
|
272
|
+
console.log(` ${'─'.repeat(40)}`);
|
|
273
|
+
console.log(` ${data.description || '(no description)'}\n`);
|
|
274
|
+
console.log(` ID: ${data.workflowId}`);
|
|
275
|
+
console.log(` Status: ${data.status}`);
|
|
276
|
+
console.log(` Cost: $${data.totalPrice} USDC`);
|
|
277
|
+
console.log(` Chain: ${data.chain || 'base'}`);
|
|
278
|
+
console.log(` Creator: ${data.creatorWallet}`);
|
|
279
|
+
console.log(` Nodes: ${data.graph?.nodes?.length || 0}`);
|
|
280
|
+
if (data.graph?.nodes?.length) {
|
|
281
|
+
console.log(`\n Pipeline:`);
|
|
282
|
+
for (const node of data.graph.nodes) {
|
|
283
|
+
const deps = node.dependsOn?.length ? ` (depends on: ${node.dependsOn.join(', ')})` : '';
|
|
284
|
+
const isOutput = node.id === data.graph.outputNode ? ' [output]' : '';
|
|
285
|
+
console.log(` → ${node.id}: ${node.endpoint}${deps}${isOutput}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (data.splits?.length) {
|
|
289
|
+
console.log(`\n Payment Split:`);
|
|
290
|
+
for (const s of data.splits) {
|
|
291
|
+
const pct = (s.basisPoints / 100).toFixed(1);
|
|
292
|
+
const usd = (parseFloat(data.totalPrice) * s.basisPoints / 10000).toFixed(4);
|
|
293
|
+
console.log(` ${s.label}: ${pct}% ($${usd})`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
console.log('');
|
|
297
|
+
}
|
|
298
|
+
catch (err) {
|
|
299
|
+
console.error(`Error: ${err.message}`);
|
|
300
|
+
process.exit(1);
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
// ─── run workflow ───
|
|
304
|
+
program
|
|
305
|
+
.command('run-workflow <id>')
|
|
306
|
+
.description('Run a workflow (x402 paid)')
|
|
307
|
+
.option('-d, --data <json>', 'JSON input', '{"query":"hello world"}')
|
|
308
|
+
.option('-k, --key <privateKey>', 'Wallet private key')
|
|
309
|
+
.action(async (id, opts) => {
|
|
310
|
+
try {
|
|
311
|
+
const privateKey = getPrivateKey(opts);
|
|
312
|
+
const body = JSON.parse(opts.data);
|
|
313
|
+
const details = await fetchJson(`${API_BASE}/api/workflows/${id}`);
|
|
314
|
+
console.error(`Running workflow "${details.name}" — cost: $${details.totalPrice} USDC`);
|
|
315
|
+
const apinow = createClient({ privateKey });
|
|
316
|
+
const result = await apinow.runWorkflow(id, body);
|
|
317
|
+
console.log(JSON.stringify(result, null, 2));
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
console.error(`Error: ${err.message}`);
|
|
321
|
+
process.exit(1);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
// ─── factory-balance ───
|
|
325
|
+
program
|
|
326
|
+
.command('factory-balance')
|
|
327
|
+
.description('Check $APINOW token balance and factory access')
|
|
328
|
+
.option('-k, --key <privateKey>', 'Wallet private key')
|
|
329
|
+
.action(async (opts) => {
|
|
330
|
+
try {
|
|
331
|
+
const { address } = getWallet(opts);
|
|
332
|
+
const data = await fetchJson(`${API_BASE}/api/user-factory/check-balance`, {
|
|
333
|
+
headers: walletHeaders(address),
|
|
334
|
+
});
|
|
335
|
+
console.log(`\n Wallet: ${address}`);
|
|
336
|
+
console.log(` Balance: ${data.balance} $APINOW`);
|
|
337
|
+
console.log(` Required: ${data.required}`);
|
|
338
|
+
console.log(` Access: ${data.hasAccess ? 'YES' : 'NO'}\n`);
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
console.error(`Error: ${err.message}`);
|
|
342
|
+
process.exit(1);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
// ─── factory-list ───
|
|
346
|
+
program
|
|
347
|
+
.command('factory-list')
|
|
348
|
+
.description('List your user-factory endpoints')
|
|
349
|
+
.option('-k, --key <privateKey>', 'Wallet private key')
|
|
350
|
+
.action(async (opts) => {
|
|
351
|
+
try {
|
|
352
|
+
const { address } = getWallet(opts);
|
|
353
|
+
const data = await fetchJson(`${API_BASE}/api/user-factory`, {
|
|
354
|
+
headers: walletHeaders(address),
|
|
355
|
+
});
|
|
356
|
+
const endpoints = data.endpoints || [];
|
|
357
|
+
if (!endpoints.length) {
|
|
358
|
+
console.log('No factory endpoints found.');
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const rows = [['ENDPOINT', 'MODEL', 'COST', 'STATUS']];
|
|
362
|
+
for (const ep of endpoints) {
|
|
363
|
+
rows.push([
|
|
364
|
+
`${ep.namespace}/${ep.endpointName}`,
|
|
365
|
+
ep.model || '—',
|
|
366
|
+
formatUsd(ep.paymentOptions),
|
|
367
|
+
ep.status || '—',
|
|
368
|
+
]);
|
|
369
|
+
}
|
|
370
|
+
printTable(rows);
|
|
371
|
+
}
|
|
372
|
+
catch (err) {
|
|
373
|
+
console.error(`Error: ${err.message}`);
|
|
374
|
+
process.exit(1);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
// ─── factory-generate ───
|
|
378
|
+
program
|
|
379
|
+
.command('factory-generate <idea>')
|
|
380
|
+
.description('Generate endpoint config from a natural-language idea')
|
|
381
|
+
.option('-k, --key <privateKey>', 'Wallet private key')
|
|
382
|
+
.action(async (idea, opts) => {
|
|
383
|
+
try {
|
|
384
|
+
const { address } = getWallet(opts);
|
|
385
|
+
console.error('Generating endpoint config…');
|
|
386
|
+
const data = await fetchJson(`${API_BASE}/api/user-factory/generate`, {
|
|
387
|
+
method: 'POST',
|
|
388
|
+
headers: walletHeaders(address),
|
|
389
|
+
body: JSON.stringify({ idea }),
|
|
390
|
+
});
|
|
391
|
+
console.log(JSON.stringify(data, null, 2));
|
|
392
|
+
}
|
|
393
|
+
catch (err) {
|
|
394
|
+
console.error(`Error: ${err.message}`);
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
// ─── factory-create ───
|
|
399
|
+
program
|
|
400
|
+
.command('factory-create')
|
|
401
|
+
.description('Create an LLM endpoint via user-factory')
|
|
402
|
+
.requiredOption('--name <name>', 'Endpoint name')
|
|
403
|
+
.requiredOption('--prompt <prompt>', 'System prompt for the LLM')
|
|
404
|
+
.option('--namespace <ns>', 'Namespace (defaults to u-<wallet>)')
|
|
405
|
+
.option('--description <desc>', 'Endpoint description')
|
|
406
|
+
.option('--model <model>', 'LLM model', 'google/gemini-2.0-flash-001')
|
|
407
|
+
.option('--price <usdc>', 'USDC price per call', '0.01')
|
|
408
|
+
.option('--recipient <wallet>', 'Payment recipient wallet')
|
|
409
|
+
.option('--input-params <json>', 'Input params JSON array')
|
|
410
|
+
.option('--output-params <json>', 'Output params JSON array')
|
|
411
|
+
.option('-k, --key <privateKey>', 'Wallet private key')
|
|
412
|
+
.action(async (opts) => {
|
|
413
|
+
try {
|
|
414
|
+
const { address } = getWallet(opts);
|
|
415
|
+
const body = {
|
|
416
|
+
name: opts.name,
|
|
417
|
+
prompt: opts.prompt,
|
|
418
|
+
model: opts.model,
|
|
419
|
+
usdcPrice: opts.price,
|
|
420
|
+
};
|
|
421
|
+
if (opts.namespace)
|
|
422
|
+
body.namespace = opts.namespace;
|
|
423
|
+
if (opts.description)
|
|
424
|
+
body.description = opts.description;
|
|
425
|
+
if (opts.recipient)
|
|
426
|
+
body.recipientWallet = opts.recipient;
|
|
427
|
+
if (opts.inputParams)
|
|
428
|
+
body.inputParams = JSON.parse(opts.inputParams);
|
|
429
|
+
if (opts.outputParams)
|
|
430
|
+
body.outputParams = JSON.parse(opts.outputParams);
|
|
431
|
+
console.error(`Creating endpoint "${opts.name}"…`);
|
|
432
|
+
const data = await fetchJson(`${API_BASE}/api/user-factory`, {
|
|
433
|
+
method: 'POST',
|
|
434
|
+
headers: walletHeaders(address),
|
|
435
|
+
body: JSON.stringify(body),
|
|
436
|
+
});
|
|
437
|
+
const ep = data.endpoint;
|
|
438
|
+
console.log(`\n Created: ${ep.namespace}/${ep.endpointName}`);
|
|
439
|
+
console.log(` Model: ${ep.model}`);
|
|
440
|
+
console.log(` Price: $${ep.price} USDC`);
|
|
441
|
+
console.log(` Try: https://apinow.fun${ep.tryUrl}`);
|
|
442
|
+
console.log(` API: https://apinow.fun${ep.apiUrl}\n`);
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
console.error(`Error: ${err.message}`);
|
|
446
|
+
process.exit(1);
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
// ─── factory-markup ───
|
|
450
|
+
program
|
|
451
|
+
.command('factory-markup <endpointId>')
|
|
452
|
+
.description('Create a markup workflow that wraps an existing endpoint')
|
|
453
|
+
.option('--markup <percent>', 'Markup percentage', '20')
|
|
454
|
+
.option('--name <name>', 'Workflow name')
|
|
455
|
+
.option('-k, --key <privateKey>', 'Wallet private key')
|
|
456
|
+
.action(async (endpointId, opts) => {
|
|
457
|
+
try {
|
|
458
|
+
const { address } = getWallet(opts);
|
|
459
|
+
const body = { endpointId, markupPercent: Number(opts.markup) };
|
|
460
|
+
if (opts.name)
|
|
461
|
+
body.workflowName = opts.name;
|
|
462
|
+
console.error(`Creating markup workflow (${opts.markup}%)…`);
|
|
463
|
+
const data = await fetchJson(`${API_BASE}/api/user-factory/markup`, {
|
|
464
|
+
method: 'POST',
|
|
465
|
+
headers: walletHeaders(address),
|
|
466
|
+
body: JSON.stringify(body),
|
|
467
|
+
});
|
|
468
|
+
const w = data.workflow;
|
|
469
|
+
console.log(`\n Created: ${w.name}`);
|
|
470
|
+
console.log(` ID: ${w.workflowId}`);
|
|
471
|
+
console.log(` Base: $${w.basePrice} USDC`);
|
|
472
|
+
console.log(` Markup: ${w.markupPercent}%`);
|
|
473
|
+
console.log(` Total: $${w.totalPrice} USDC`);
|
|
474
|
+
console.log(` View: https://apinow.fun${w.viewUrl}\n`);
|
|
475
|
+
}
|
|
476
|
+
catch (err) {
|
|
477
|
+
console.error(`Error: ${err.message}`);
|
|
478
|
+
process.exit(1);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
// ─── factory-test ───
|
|
482
|
+
program
|
|
483
|
+
.command('factory-test <endpoint>')
|
|
484
|
+
.description('Test-call an endpoint without payment')
|
|
485
|
+
.option('-d, --data <json>', 'JSON input')
|
|
486
|
+
.option('--save', 'Save as example')
|
|
487
|
+
.option('-k, --key <privateKey>', 'Wallet private key')
|
|
488
|
+
.action(async (endpoint, opts) => {
|
|
489
|
+
try {
|
|
490
|
+
if (!endpoint.includes('/'))
|
|
491
|
+
throw new Error('Format: namespace/endpoint-name');
|
|
492
|
+
const { address } = getWallet(opts);
|
|
493
|
+
const [namespace, endpointName] = endpoint.split('/');
|
|
494
|
+
const body = { namespace, endpointName };
|
|
495
|
+
if (opts.data)
|
|
496
|
+
body.input = JSON.parse(opts.data);
|
|
497
|
+
if (opts.save)
|
|
498
|
+
body.saveExample = true;
|
|
499
|
+
console.error(`Testing ${endpoint}…`);
|
|
500
|
+
const data = await fetchJson(`${API_BASE}/api/user-factory/test-call`, {
|
|
501
|
+
method: 'POST',
|
|
502
|
+
headers: walletHeaders(address),
|
|
503
|
+
body: JSON.stringify(body),
|
|
504
|
+
});
|
|
505
|
+
console.log(JSON.stringify(data.output, null, 2));
|
|
506
|
+
if (data.saved)
|
|
507
|
+
console.error('(saved as example)');
|
|
508
|
+
}
|
|
509
|
+
catch (err) {
|
|
510
|
+
console.error(`Error: ${err.message}`);
|
|
511
|
+
process.exit(1);
|
|
512
|
+
}
|
|
513
|
+
});
|
|
219
514
|
program.parse();
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,76 @@ export declare function createClient(config: ApinowConfig): {
|
|
|
27
27
|
* Get public endpoint info (free, no payment).
|
|
28
28
|
*/
|
|
29
29
|
info(namespace: string, endpointName: string): Promise<any>;
|
|
30
|
+
/**
|
|
31
|
+
* List workflows. Optionally filter by creator or status.
|
|
32
|
+
*/
|
|
33
|
+
listWorkflows(opts?: {
|
|
34
|
+
creator?: string;
|
|
35
|
+
status?: string;
|
|
36
|
+
limit?: number;
|
|
37
|
+
}): Promise<any>;
|
|
38
|
+
/**
|
|
39
|
+
* Get workflow details by ID.
|
|
40
|
+
*/
|
|
41
|
+
getWorkflow(workflowId: string): Promise<any>;
|
|
42
|
+
/**
|
|
43
|
+
* Run a workflow. Handles x402 payment automatically.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* const result = await apinow.runWorkflow('90931d9c8fb94df9', { query: 'hello world' });
|
|
47
|
+
*/
|
|
48
|
+
runWorkflow(workflowId: string, input: Record<string, any>): Promise<any>;
|
|
49
|
+
/**
|
|
50
|
+
* Check $APINOW token balance and factory access.
|
|
51
|
+
*/
|
|
52
|
+
factoryBalance(): Promise<any>;
|
|
53
|
+
/**
|
|
54
|
+
* List your user-factory endpoints.
|
|
55
|
+
*/
|
|
56
|
+
factoryList(): Promise<any>;
|
|
57
|
+
/**
|
|
58
|
+
* Generate endpoint config from a natural-language idea.
|
|
59
|
+
*/
|
|
60
|
+
factoryGenerate(idea: string): Promise<any>;
|
|
61
|
+
/**
|
|
62
|
+
* Create an LLM endpoint via user-factory.
|
|
63
|
+
*/
|
|
64
|
+
factoryCreate(config: {
|
|
65
|
+
name: string;
|
|
66
|
+
prompt: string;
|
|
67
|
+
namespace?: string;
|
|
68
|
+
description?: string;
|
|
69
|
+
model?: string;
|
|
70
|
+
usdcPrice?: string;
|
|
71
|
+
recipientWallet?: string;
|
|
72
|
+
inputParams?: Array<{
|
|
73
|
+
name: string;
|
|
74
|
+
type: string;
|
|
75
|
+
description?: string;
|
|
76
|
+
}>;
|
|
77
|
+
outputParams?: Array<{
|
|
78
|
+
name: string;
|
|
79
|
+
type: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
}>;
|
|
82
|
+
}): Promise<any>;
|
|
83
|
+
/**
|
|
84
|
+
* Create a markup workflow wrapping an existing endpoint.
|
|
85
|
+
*/
|
|
86
|
+
factoryMarkup(opts: {
|
|
87
|
+
endpointId: string;
|
|
88
|
+
markupPercent?: number;
|
|
89
|
+
workflowName?: string;
|
|
90
|
+
}): Promise<any>;
|
|
91
|
+
/**
|
|
92
|
+
* Test-call an endpoint without payment (free, server-side LLM call).
|
|
93
|
+
*/
|
|
94
|
+
factoryTestCall(opts: {
|
|
95
|
+
namespace: string;
|
|
96
|
+
endpointName: string;
|
|
97
|
+
input?: any;
|
|
98
|
+
saveExample?: boolean;
|
|
99
|
+
}): Promise<any>;
|
|
30
100
|
/**
|
|
31
101
|
* The underlying x402-wrapped fetch, for advanced use.
|
|
32
102
|
*/
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,125 @@ export function createClient(config) {
|
|
|
58
58
|
throw new Error(`Failed to fetch info: ${res.status}`);
|
|
59
59
|
return res.json();
|
|
60
60
|
},
|
|
61
|
+
// ─── Workflows ───
|
|
62
|
+
/**
|
|
63
|
+
* List workflows. Optionally filter by creator or status.
|
|
64
|
+
*/
|
|
65
|
+
async listWorkflows(opts = {}) {
|
|
66
|
+
const params = new URLSearchParams();
|
|
67
|
+
if (opts.limit)
|
|
68
|
+
params.set('limit', String(opts.limit));
|
|
69
|
+
if (opts.creator)
|
|
70
|
+
params.set('creator', opts.creator);
|
|
71
|
+
if (opts.status)
|
|
72
|
+
params.set('status', opts.status);
|
|
73
|
+
const res = await fetch(`${baseUrl}/api/workflows?${params}`);
|
|
74
|
+
if (!res.ok)
|
|
75
|
+
throw new Error(`Failed to list workflows: ${res.status}`);
|
|
76
|
+
return res.json();
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Get workflow details by ID.
|
|
80
|
+
*/
|
|
81
|
+
async getWorkflow(workflowId) {
|
|
82
|
+
const res = await fetch(`${baseUrl}/api/workflows/${workflowId}`);
|
|
83
|
+
if (!res.ok)
|
|
84
|
+
throw new Error(`Failed to get workflow: ${res.status}`);
|
|
85
|
+
return res.json();
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* Run a workflow. Handles x402 payment automatically.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* const result = await apinow.runWorkflow('90931d9c8fb94df9', { query: 'hello world' });
|
|
92
|
+
*/
|
|
93
|
+
async runWorkflow(workflowId, input) {
|
|
94
|
+
return this.call(`/api/workflows/${workflowId}/run`, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
body: input,
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
// ─── User Factory ───
|
|
100
|
+
/**
|
|
101
|
+
* Check $APINOW token balance and factory access.
|
|
102
|
+
*/
|
|
103
|
+
async factoryBalance() {
|
|
104
|
+
const res = await fetch(`${baseUrl}/api/user-factory/check-balance`, {
|
|
105
|
+
headers: { 'x-wallet-address': account.address },
|
|
106
|
+
});
|
|
107
|
+
if (!res.ok)
|
|
108
|
+
throw new Error(`Failed to check balance: ${res.status}`);
|
|
109
|
+
return res.json();
|
|
110
|
+
},
|
|
111
|
+
/**
|
|
112
|
+
* List your user-factory endpoints.
|
|
113
|
+
*/
|
|
114
|
+
async factoryList() {
|
|
115
|
+
const res = await fetch(`${baseUrl}/api/user-factory`, {
|
|
116
|
+
headers: { 'x-wallet-address': account.address },
|
|
117
|
+
});
|
|
118
|
+
if (!res.ok)
|
|
119
|
+
throw new Error(`Failed to list factory endpoints: ${res.status}`);
|
|
120
|
+
return res.json();
|
|
121
|
+
},
|
|
122
|
+
/**
|
|
123
|
+
* Generate endpoint config from a natural-language idea.
|
|
124
|
+
*/
|
|
125
|
+
async factoryGenerate(idea) {
|
|
126
|
+
const res = await fetch(`${baseUrl}/api/user-factory/generate`, {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: { 'Content-Type': 'application/json', 'x-wallet-address': account.address },
|
|
129
|
+
body: JSON.stringify({ idea }),
|
|
130
|
+
});
|
|
131
|
+
if (!res.ok)
|
|
132
|
+
throw new Error(`Failed to generate: ${res.status}`);
|
|
133
|
+
return res.json();
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Create an LLM endpoint via user-factory.
|
|
137
|
+
*/
|
|
138
|
+
async factoryCreate(config) {
|
|
139
|
+
const res = await fetch(`${baseUrl}/api/user-factory`, {
|
|
140
|
+
method: 'POST',
|
|
141
|
+
headers: { 'Content-Type': 'application/json', 'x-wallet-address': account.address },
|
|
142
|
+
body: JSON.stringify(config),
|
|
143
|
+
});
|
|
144
|
+
if (!res.ok) {
|
|
145
|
+
const text = await res.text();
|
|
146
|
+
throw new Error(`Failed to create endpoint: ${res.status} ${text}`);
|
|
147
|
+
}
|
|
148
|
+
return res.json();
|
|
149
|
+
},
|
|
150
|
+
/**
|
|
151
|
+
* Create a markup workflow wrapping an existing endpoint.
|
|
152
|
+
*/
|
|
153
|
+
async factoryMarkup(opts) {
|
|
154
|
+
const res = await fetch(`${baseUrl}/api/user-factory/markup`, {
|
|
155
|
+
method: 'POST',
|
|
156
|
+
headers: { 'Content-Type': 'application/json', 'x-wallet-address': account.address },
|
|
157
|
+
body: JSON.stringify(opts),
|
|
158
|
+
});
|
|
159
|
+
if (!res.ok) {
|
|
160
|
+
const text = await res.text();
|
|
161
|
+
throw new Error(`Failed to create markup: ${res.status} ${text}`);
|
|
162
|
+
}
|
|
163
|
+
return res.json();
|
|
164
|
+
},
|
|
165
|
+
/**
|
|
166
|
+
* Test-call an endpoint without payment (free, server-side LLM call).
|
|
167
|
+
*/
|
|
168
|
+
async factoryTestCall(opts) {
|
|
169
|
+
const res = await fetch(`${baseUrl}/api/user-factory/test-call`, {
|
|
170
|
+
method: 'POST',
|
|
171
|
+
headers: { 'Content-Type': 'application/json', 'x-wallet-address': account.address },
|
|
172
|
+
body: JSON.stringify(opts),
|
|
173
|
+
});
|
|
174
|
+
if (!res.ok) {
|
|
175
|
+
const text = await res.text();
|
|
176
|
+
throw new Error(`Failed to test call: ${res.status} ${text}`);
|
|
177
|
+
}
|
|
178
|
+
return res.json();
|
|
179
|
+
},
|
|
61
180
|
/**
|
|
62
181
|
* The underlying x402-wrapped fetch, for advanced use.
|
|
63
182
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apinow-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Pay-per-call API SDK & CLI for APINow.fun — wraps x402 so you don't have to",
|
|
3
|
+
"version": "0.17.0",
|
|
4
|
+
"description": "Pay-per-call API SDK & CLI for APINow.fun — endpoints + workflows, wraps x402 so you don't have to",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
"web3",
|
|
25
25
|
"ai",
|
|
26
26
|
"llm",
|
|
27
|
-
"cli"
|
|
27
|
+
"cli",
|
|
28
|
+
"workflow",
|
|
29
|
+
"dag",
|
|
30
|
+
"user-factory"
|
|
28
31
|
],
|
|
29
32
|
"author": "ApiNow.fun",
|
|
30
33
|
"license": "MIT",
|