clawmoney 0.9.1 → 0.9.2

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.
@@ -16,6 +16,7 @@ interface CallOptions {
16
16
  skill: string;
17
17
  input?: string;
18
18
  timeout?: string;
19
+ pay?: boolean;
19
20
  }
20
21
  export declare function hubCallCommand(options: CallOptions): Promise<void>;
21
22
  interface RegisterOptions {
@@ -4,7 +4,8 @@ import { homedir } from "node:os";
4
4
  import chalk from "chalk";
5
5
  import ora from "ora";
6
6
  import { requireConfig } from "../utils/config.js";
7
- import { apiGet, apiPost } from "../utils/api.js";
7
+ import { apiGet, apiPost, getApiBase } from "../utils/api.js";
8
+ import { awalExec } from "../utils/awal.js";
8
9
  import { readPid, isPidAlive, removePid } from "../hub/provider.js";
9
10
  const LOG_FILE = join(homedir(), ".clawmoney", "provider.log");
10
11
  // ── hub start ──
@@ -155,31 +156,74 @@ export async function hubCallCommand(options) {
155
156
  const timeout = options.timeout ? parseInt(options.timeout, 10) : 60;
156
157
  const spinner = ora(`Calling ${options.agent}/${options.skill}...`).start();
157
158
  try {
158
- // gateway/invoke takes agent_id, skill, timeout as query params; input_data as POST body
159
- const qs = new URLSearchParams({
160
- agent_id: options.agent,
161
- skill: options.skill,
162
- timeout: String(timeout),
163
- payment_method: "ledger",
164
- });
165
- const resp = await apiPost(`/api/v1/hub/gateway/invoke?${qs}`, inputData, config.api_key);
166
- if (!resp.ok) {
167
- const raw = resp.data && typeof resp.data === "object" && "detail" in resp.data
168
- ? resp.data.detail
169
- : resp.data;
170
- const detail = typeof raw === "string" ? raw : JSON.stringify(raw);
171
- spinner.fail(chalk.red(`Call failed (${resp.status}): ${detail}`));
172
- process.exit(1);
159
+ if (options.pay) {
160
+ // x402 payment: two steps
161
+ // Step 1: Pay via x402 to the payment endpoint (USDC → PaySplitter)
162
+ spinner.text = `Paying for ${options.agent}/${options.skill} via x402...`;
163
+ const payUrl = `${getApiBase()}/api/v1/hub/gateway/pay?agent_id=${encodeURIComponent(options.agent)}&skill=${encodeURIComponent(options.skill)}`;
164
+ let payResult;
165
+ try {
166
+ payResult = await awalExec(["x402", "pay", payUrl]);
167
+ }
168
+ catch (err) {
169
+ spinner.fail(chalk.red(`Payment failed: ${err.message}`));
170
+ process.exit(1);
171
+ }
172
+ // Step 2: Call invoke with ledger (payment already settled on-chain)
173
+ spinner.text = `Executing ${options.agent}/${options.skill}...`;
174
+ const qs = new URLSearchParams({
175
+ agent_id: options.agent,
176
+ skill: options.skill,
177
+ timeout: String(timeout),
178
+ payment_method: "ledger",
179
+ });
180
+ const resp = await apiPost(`/api/v1/hub/gateway/invoke?${qs}`, inputData, config.api_key);
181
+ if (!resp.ok) {
182
+ const raw = resp.data && typeof resp.data === "object" && "detail" in resp.data
183
+ ? resp.data.detail
184
+ : resp.data;
185
+ const detail = typeof raw === "string" ? raw : JSON.stringify(raw);
186
+ spinner.fail(chalk.red(`Call failed (${resp.status}): ${detail}`));
187
+ process.exit(1);
188
+ }
189
+ const result = resp.data;
190
+ spinner.succeed(chalk.green("Call completed (x402 paid)!"));
191
+ console.log("");
192
+ console.log(` ${chalk.bold("Order:")} ${result.id ?? "-"}`);
193
+ console.log(` ${chalk.bold("Duration:")} ${typeof result.duration === "number" ? result.duration.toFixed(1) + "s" : "-"}`);
194
+ console.log(` ${chalk.bold("Cost:")} $${typeof result.price === "number" ? result.price.toFixed(3) : "-"} (USDC)`);
195
+ console.log(` ${chalk.bold("Payment:")} ${JSON.stringify(payResult.data).slice(0, 100)}`);
196
+ console.log("");
197
+ console.log(chalk.bold(" Output:"));
198
+ console.log(chalk.cyan(" " + JSON.stringify(result.output_data ?? result.output ?? {}, null, 2).replace(/\n/g, "\n ")));
199
+ }
200
+ else {
201
+ // Ledger payment (no real USDC transfer)
202
+ const qs = new URLSearchParams({
203
+ agent_id: options.agent,
204
+ skill: options.skill,
205
+ timeout: String(timeout),
206
+ payment_method: "ledger",
207
+ });
208
+ const resp = await apiPost(`/api/v1/hub/gateway/invoke?${qs}`, inputData, config.api_key);
209
+ if (!resp.ok) {
210
+ const raw = resp.data && typeof resp.data === "object" && "detail" in resp.data
211
+ ? resp.data.detail
212
+ : resp.data;
213
+ const detail = typeof raw === "string" ? raw : JSON.stringify(raw);
214
+ spinner.fail(chalk.red(`Call failed (${resp.status}): ${detail}`));
215
+ process.exit(1);
216
+ }
217
+ const result = resp.data;
218
+ spinner.succeed(chalk.green("Call completed!"));
219
+ console.log("");
220
+ console.log(` ${chalk.bold("Order:")} ${result.id ?? "-"}`);
221
+ console.log(` ${chalk.bold("Duration:")} ${typeof result.duration === "number" ? result.duration.toFixed(1) + "s" : "-"}`);
222
+ console.log(` ${chalk.bold("Cost:")} $${typeof result.price === "number" ? result.price.toFixed(3) : "-"}`);
223
+ console.log("");
224
+ console.log(chalk.bold(" Output:"));
225
+ console.log(chalk.cyan(" " + JSON.stringify(result.output_data ?? result.output ?? {}, null, 2).replace(/\n/g, "\n ")));
173
226
  }
174
- const result = resp.data;
175
- spinner.succeed(chalk.green("Call completed!"));
176
- console.log("");
177
- console.log(` ${chalk.bold("Order:")} ${result.id ?? "-"}`);
178
- console.log(` ${chalk.bold("Duration:")} ${typeof result.duration === "number" ? result.duration.toFixed(1) + "s" : "-"}`);
179
- console.log(` ${chalk.bold("Cost:")} $${typeof result.price === "number" ? result.price.toFixed(3) : "-"}`);
180
- console.log("");
181
- console.log(chalk.bold(" Output:"));
182
- console.log(chalk.cyan(" " + JSON.stringify(result.output_data ?? result.output ?? {}, null, 2).replace(/\n/g, "\n ")));
183
227
  }
184
228
  catch (err) {
185
229
  spinner.fail(chalk.red("Call failed"));
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ const program = new Command();
11
11
  program
12
12
  .name('clawmoney')
13
13
  .description('ClawMoney CLI -- Earn rewards with your AI agent')
14
- .version('0.9.1');
14
+ .version('0.9.2');
15
15
  // setup
16
16
  program
17
17
  .command('setup')
@@ -232,6 +232,7 @@ hub
232
232
  .requiredOption('-s, --skill <skill>', 'Skill name to invoke')
233
233
  .option('-i, --input <json>', 'Input parameters as JSON')
234
234
  .option('-t, --timeout <seconds>', 'Timeout in seconds', '60')
235
+ .option('--pay', 'Pay with USDC via x402 (default: ledger/free)')
235
236
  .action(async (options) => {
236
237
  try {
237
238
  await hubCallCommand(options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {