agstell-cli 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +98 -144
- package/dist/index.d.ts +12 -3
- package/dist/index.js +53 -85
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -42,7 +42,11 @@ function readRegistryCache() {
|
|
|
42
42
|
try {
|
|
43
43
|
if (!fs.existsSync(REGISTRY_CACHE_FILE)) return null;
|
|
44
44
|
const data = fs.readFileSync(REGISTRY_CACHE_FILE, "utf-8");
|
|
45
|
-
|
|
45
|
+
const parsed = JSON.parse(data);
|
|
46
|
+
if (parsed.apis?.length > 0 && !("priceXlm" in parsed.apis[0])) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return parsed;
|
|
46
50
|
} catch {
|
|
47
51
|
return null;
|
|
48
52
|
}
|
|
@@ -64,11 +68,11 @@ var CONTRACTS = {
|
|
|
64
68
|
}
|
|
65
69
|
};
|
|
66
70
|
var DEFAULT_CONFIG = {
|
|
67
|
-
stellarNetwork: "
|
|
68
|
-
marketplaceUrl: "https://
|
|
71
|
+
stellarNetwork: "mainnet",
|
|
72
|
+
marketplaceUrl: "https://steller-web.vercel.app",
|
|
69
73
|
budgetLimit: 10,
|
|
70
|
-
// 10
|
|
71
|
-
contractId: CONTRACTS.
|
|
74
|
+
// 10 XLM default
|
|
75
|
+
contractId: CONTRACTS.mainnet.budgetEnforcer
|
|
72
76
|
};
|
|
73
77
|
function ensureConfigDir() {
|
|
74
78
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
@@ -122,22 +126,18 @@ var StellarSdk = __toESM(require("@stellar/stellar-sdk"));
|
|
|
122
126
|
var NETWORKS = {
|
|
123
127
|
testnet: {
|
|
124
128
|
networkPassphrase: StellarSdk.Networks.TESTNET,
|
|
125
|
-
horizonUrl: "https://horizon-testnet.stellar.org"
|
|
126
|
-
sorobanUrl: "https://soroban-testnet.stellar.org"
|
|
129
|
+
horizonUrl: "https://horizon-testnet.stellar.org"
|
|
127
130
|
},
|
|
128
131
|
mainnet: {
|
|
129
132
|
networkPassphrase: StellarSdk.Networks.PUBLIC,
|
|
130
|
-
horizonUrl: "https://horizon.stellar.org"
|
|
131
|
-
sorobanUrl: "https://mainnet.stellar.org"
|
|
133
|
+
horizonUrl: "https://horizon.stellar.org"
|
|
132
134
|
}
|
|
133
135
|
};
|
|
134
|
-
var USDC_TESTNET_ISSUER = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5";
|
|
135
|
-
var USDC_MAINNET_ISSUER = "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN";
|
|
136
136
|
var StellarClient = class {
|
|
137
137
|
network;
|
|
138
138
|
server;
|
|
139
139
|
keypair = null;
|
|
140
|
-
constructor(network = "
|
|
140
|
+
constructor(network = "mainnet") {
|
|
141
141
|
this.network = network;
|
|
142
142
|
const config2 = NETWORKS[network];
|
|
143
143
|
this.server = new StellarSdk.Horizon.Server(config2.horizonUrl);
|
|
@@ -153,27 +153,21 @@ var StellarClient = class {
|
|
|
153
153
|
try {
|
|
154
154
|
const account = await this.server.loadAccount(this.keypair.publicKey());
|
|
155
155
|
let xlmBalance = "0";
|
|
156
|
-
let usdcBalance = "0";
|
|
157
|
-
const usdcIssuer = this.network === "testnet" ? USDC_TESTNET_ISSUER : USDC_MAINNET_ISSUER;
|
|
158
156
|
for (const balance of account.balances) {
|
|
159
157
|
if (balance.asset_type === "native") {
|
|
160
158
|
xlmBalance = balance.balance;
|
|
161
|
-
} else if (balance.asset_type !== "liquidity_pool_shares" && balance.asset_code === "USDC" && balance.asset_issuer === usdcIssuer) {
|
|
162
|
-
usdcBalance = balance.balance;
|
|
163
159
|
}
|
|
164
160
|
}
|
|
165
161
|
return {
|
|
166
162
|
publicKey: this.keypair.publicKey(),
|
|
167
163
|
network: this.network,
|
|
168
|
-
xlmBalance
|
|
169
|
-
usdcBalance
|
|
164
|
+
xlmBalance
|
|
170
165
|
};
|
|
171
166
|
} catch (error) {
|
|
172
167
|
return {
|
|
173
168
|
publicKey: this.keypair.publicKey(),
|
|
174
169
|
network: this.network,
|
|
175
|
-
xlmBalance: "0"
|
|
176
|
-
usdcBalance: "0"
|
|
170
|
+
xlmBalance: "0"
|
|
177
171
|
};
|
|
178
172
|
}
|
|
179
173
|
}
|
|
@@ -190,26 +184,25 @@ var StellarClient = class {
|
|
|
190
184
|
}
|
|
191
185
|
return null;
|
|
192
186
|
}
|
|
187
|
+
/** Send native XLM payment */
|
|
193
188
|
async sendPayment(destination, amount, memo) {
|
|
194
189
|
if (!this.keypair) return null;
|
|
195
190
|
try {
|
|
196
191
|
const account = await this.server.loadAccount(this.keypair.publicKey());
|
|
197
|
-
const
|
|
198
|
-
const usdcAsset = new StellarSdk.Asset("USDC", usdcIssuer);
|
|
199
|
-
const transaction = new StellarSdk.TransactionBuilder(account, {
|
|
192
|
+
const transactionBuilder = new StellarSdk.TransactionBuilder(account, {
|
|
200
193
|
fee: StellarSdk.BASE_FEE,
|
|
201
194
|
networkPassphrase: NETWORKS[this.network].networkPassphrase
|
|
202
195
|
}).addOperation(
|
|
203
196
|
StellarSdk.Operation.payment({
|
|
204
197
|
destination,
|
|
205
|
-
asset:
|
|
198
|
+
asset: StellarSdk.Asset.native(),
|
|
206
199
|
amount
|
|
207
200
|
})
|
|
208
201
|
).setTimeout(30);
|
|
209
202
|
if (memo) {
|
|
210
|
-
|
|
203
|
+
transactionBuilder.addMemo(StellarSdk.Memo.text(memo.substring(0, 28)));
|
|
211
204
|
}
|
|
212
|
-
const builtTx =
|
|
205
|
+
const builtTx = transactionBuilder.build();
|
|
213
206
|
builtTx.sign(this.keypair);
|
|
214
207
|
const result = await this.server.submitTransaction(builtTx);
|
|
215
208
|
return {
|
|
@@ -217,8 +210,10 @@ var StellarClient = class {
|
|
|
217
210
|
success: true
|
|
218
211
|
};
|
|
219
212
|
} catch (error) {
|
|
220
|
-
|
|
221
|
-
|
|
213
|
+
const axiosLike = error;
|
|
214
|
+
const resultCodes = axiosLike?.response?.data?.extras?.result_codes;
|
|
215
|
+
const detail = resultCodes ? `Horizon rejected tx: ${JSON.stringify(resultCodes)}` : error instanceof Error ? error.message : "Unknown error";
|
|
216
|
+
throw new Error(detail);
|
|
222
217
|
}
|
|
223
218
|
}
|
|
224
219
|
async verifyTransaction(txHash) {
|
|
@@ -242,64 +237,24 @@ var StellarClient = class {
|
|
|
242
237
|
var REGISTRY_TTL_MS = 60 * 60 * 1e3;
|
|
243
238
|
var FALLBACK_REGISTRY = [
|
|
244
239
|
{
|
|
245
|
-
name: "
|
|
246
|
-
slug: "
|
|
247
|
-
description: "
|
|
248
|
-
category: "Data",
|
|
249
|
-
priceUsdc: 1e-3,
|
|
250
|
-
endpoint: "/api/proxy/weather",
|
|
251
|
-
method: "GET",
|
|
252
|
-
provider: "AgentMarket"
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
name: "Air Quality",
|
|
256
|
-
slug: "air-quality",
|
|
257
|
-
description: "Get real-time air quality index and pollution data",
|
|
258
|
-
category: "Data",
|
|
259
|
-
priceUsdc: 1e-3,
|
|
260
|
-
endpoint: "/api/proxy/air-quality",
|
|
261
|
-
method: "GET",
|
|
262
|
-
provider: "AgentMarket"
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
name: "News",
|
|
266
|
-
slug: "news",
|
|
267
|
-
description: "Fetch latest news headlines by topic",
|
|
268
|
-
category: "Data",
|
|
269
|
-
priceUsdc: 2e-3,
|
|
270
|
-
endpoint: "/api/proxy/news",
|
|
271
|
-
method: "GET",
|
|
272
|
-
provider: "AgentMarket"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
name: "Currency Exchange",
|
|
276
|
-
slug: "currency",
|
|
277
|
-
description: "Convert between currencies with live rates",
|
|
240
|
+
name: "Stock Analyst",
|
|
241
|
+
slug: "stock-analyst",
|
|
242
|
+
description: "Live Yahoo Finance data + Gemini sentiment analysis",
|
|
278
243
|
category: "Finance",
|
|
279
|
-
|
|
280
|
-
endpoint: "/api/proxy/
|
|
244
|
+
priceXlm: 0.1,
|
|
245
|
+
endpoint: "/api/proxy/stock-analyst",
|
|
281
246
|
method: "GET",
|
|
282
247
|
provider: "AgentMarket"
|
|
283
248
|
},
|
|
284
249
|
{
|
|
285
|
-
name: "
|
|
286
|
-
slug: "
|
|
287
|
-
description: "
|
|
288
|
-
category: "
|
|
289
|
-
|
|
290
|
-
endpoint: "/api/proxy/
|
|
250
|
+
name: "Trading Advisor",
|
|
251
|
+
slug: "trading-advisor",
|
|
252
|
+
description: "Two-stage Gemini reasoning \u2192 BUY/HOLD/SELL with targets",
|
|
253
|
+
category: "Finance",
|
|
254
|
+
priceXlm: 0.5,
|
|
255
|
+
endpoint: "/api/proxy/trading-advisor",
|
|
291
256
|
method: "GET",
|
|
292
257
|
provider: "AgentMarket"
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
name: "AI Inference",
|
|
296
|
-
slug: "ai",
|
|
297
|
-
description: "Run AI inference queries (GPT, Claude)",
|
|
298
|
-
category: "AI",
|
|
299
|
-
priceUsdc: 5e-3,
|
|
300
|
-
endpoint: "/api/proxy/ai",
|
|
301
|
-
method: "POST",
|
|
302
|
-
provider: "AgentMarket"
|
|
303
258
|
}
|
|
304
259
|
];
|
|
305
260
|
var _registry = [...FALLBACK_REGISTRY];
|
|
@@ -309,10 +264,11 @@ function toApiInfo(entry) {
|
|
|
309
264
|
slug: entry.slug,
|
|
310
265
|
description: entry.description,
|
|
311
266
|
category: entry.category,
|
|
312
|
-
|
|
267
|
+
priceXlm: entry.price.amount,
|
|
313
268
|
endpoint: entry.endpoint,
|
|
314
269
|
method: entry.method,
|
|
315
|
-
provider: entry.provider.name
|
|
270
|
+
provider: entry.provider.name,
|
|
271
|
+
params: Array.isArray(entry.input?.params) ? entry.input.params : []
|
|
316
272
|
};
|
|
317
273
|
}
|
|
318
274
|
async function refreshRegistry(marketplaceUrl) {
|
|
@@ -375,13 +331,25 @@ async function callApi(slug, params, stellarClient) {
|
|
|
375
331
|
if (!wallet) {
|
|
376
332
|
return { success: false, error: "Wallet not configured. Run: agentmarket init" };
|
|
377
333
|
}
|
|
378
|
-
const
|
|
379
|
-
|
|
334
|
+
const xlmBalance = parseFloat(wallet.xlmBalance);
|
|
335
|
+
const STELLAR_MIN_RESERVE = 1;
|
|
336
|
+
const spendable = Math.max(0, xlmBalance - STELLAR_MIN_RESERVE);
|
|
337
|
+
if (spendable < api.priceXlm) {
|
|
380
338
|
return {
|
|
381
339
|
success: false,
|
|
382
|
-
error: `Insufficient
|
|
340
|
+
error: `Insufficient spendable XLM. Need ${api.priceXlm} XLM (balance: ${xlmBalance} XLM, ${STELLAR_MIN_RESERVE} XLM reserved by Stellar \u2014 spendable: ${spendable.toFixed(4)} XLM)`
|
|
383
341
|
};
|
|
384
342
|
}
|
|
343
|
+
if (api.params?.length) {
|
|
344
|
+
const missing = api.params.filter((p) => p.required && (params[p.name] === void 0 || params[p.name] === null || params[p.name] === "")).map((p) => ` --${p.name} (${p.type}): ${p.description}`);
|
|
345
|
+
if (missing.length > 0) {
|
|
346
|
+
return {
|
|
347
|
+
success: false,
|
|
348
|
+
error: `Missing required params \u2014 no payment made:
|
|
349
|
+
${missing.join("\n")}`
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
}
|
|
385
353
|
const baseUrl = config2.marketplaceUrl;
|
|
386
354
|
const initialRequest = buildRequest(api, baseUrl, params);
|
|
387
355
|
try {
|
|
@@ -394,7 +362,12 @@ async function callApi(slug, params, stellarClient) {
|
|
|
394
362
|
const recipient = paymentDetails.payment.recipient;
|
|
395
363
|
const amount = paymentDetails.payment.amount;
|
|
396
364
|
const memo = paymentDetails.payment?.memo || `am:${slug}:${Date.now()}`;
|
|
397
|
-
|
|
365
|
+
let paymentResult;
|
|
366
|
+
try {
|
|
367
|
+
paymentResult = await stellarClient.sendPayment(recipient, amount, memo);
|
|
368
|
+
} catch (err) {
|
|
369
|
+
return { success: false, error: err instanceof Error ? err.message : "Payment failed" };
|
|
370
|
+
}
|
|
398
371
|
if (!paymentResult?.success) {
|
|
399
372
|
return { success: false, error: "Payment failed" };
|
|
400
373
|
}
|
|
@@ -414,7 +387,7 @@ async function callApi(slug, params, stellarClient) {
|
|
|
414
387
|
success: false,
|
|
415
388
|
error: `API call failed: ${retryResponse.status}`,
|
|
416
389
|
txHash: paymentResult.txHash,
|
|
417
|
-
amountPaid: api.
|
|
390
|
+
amountPaid: api.priceXlm
|
|
418
391
|
};
|
|
419
392
|
}
|
|
420
393
|
const data = await retryResponse.json();
|
|
@@ -422,10 +395,10 @@ async function callApi(slug, params, stellarClient) {
|
|
|
422
395
|
appendHistory({
|
|
423
396
|
api: slug,
|
|
424
397
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
425
|
-
amount: api.
|
|
398
|
+
amount: api.priceXlm,
|
|
426
399
|
txHash: paymentResult.txHash
|
|
427
400
|
});
|
|
428
|
-
return { success: true, data, txHash: paymentResult.txHash, amountPaid: api.
|
|
401
|
+
return { success: true, data, txHash: paymentResult.txHash, amountPaid: api.priceXlm, latencyMs };
|
|
429
402
|
}
|
|
430
403
|
if (initialResponse.ok) {
|
|
431
404
|
const data = await initialResponse.json();
|
|
@@ -444,15 +417,15 @@ async function callApi(slug, params, stellarClient) {
|
|
|
444
417
|
dotenv.config();
|
|
445
418
|
var program = new import_commander.Command();
|
|
446
419
|
var banner = `
|
|
447
|
-
_ _ __ __ _ _
|
|
448
|
-
/ \\ __ _ ___ _ __ | |_| \\/ | __ _ _ __| | _____| |_
|
|
420
|
+
_ _ __ __ _ _
|
|
421
|
+
/ \\ __ _ ___ _ __ | |_| \\/ | __ _ _ __| | _____| |_
|
|
449
422
|
/ _ \\ / _\` |/ _ \\ '_ \\| __| |\\/| |/ _\` | '__| |/ / _ \\ __|
|
|
450
|
-
/ ___ \\ (_| | __/ | | | |_| | | | (_| | | | < __/ |_
|
|
423
|
+
/ ___ \\ (_| | __/ | | | |_| | | | (_| | | | < __/ |_
|
|
451
424
|
/_/ \\_\\__, |\\___|_| |_|\\__|_| |_|\\__,_|_| |_|\\_\\___|\\__|
|
|
452
|
-
|___/
|
|
425
|
+
|___/
|
|
453
426
|
`;
|
|
454
|
-
program.name("agentmarket").description("AgentMarket CLI - Payment IS Authentication").version("0.
|
|
455
|
-
program.command("init").description("Initialize AgentMarket CLI with your wallet").option("-k, --key <secret>", "Stellar secret key").option("-n, --network <network>", "Stellar network (testnet/mainnet)", "
|
|
427
|
+
program.name("agentmarket").description("AgentMarket CLI - Payment IS Authentication").version("0.2.0").addHelpText("beforeAll", import_chalk.default.cyan(banner));
|
|
428
|
+
program.command("init").description("Initialize AgentMarket CLI with your wallet").option("-k, --key <secret>", "Stellar secret key").option("-n, --network <network>", "Stellar network (testnet/mainnet)", "mainnet").option("--generate", "Generate a new Stellar keypair").action(async (options) => {
|
|
456
429
|
console.log(import_chalk.default.cyan(banner));
|
|
457
430
|
console.log(import_chalk.default.bold("\nAgentMarket CLI Setup\n"));
|
|
458
431
|
let secretKey = options.key;
|
|
@@ -499,8 +472,7 @@ program.command("init").description("Initialize AgentMarket CLI with your wallet
|
|
|
499
472
|
const wallet = await stellarClient.getWalletInfo();
|
|
500
473
|
if (wallet) {
|
|
501
474
|
spinner.succeed("Wallet connected!");
|
|
502
|
-
console.log(import_chalk.default.bold(` XLM Balance: `) + wallet.xlmBalance + " XLM");
|
|
503
|
-
console.log(import_chalk.default.bold(` USDC Balance:`) + wallet.usdcBalance + " USDC");
|
|
475
|
+
console.log(import_chalk.default.bold(` XLM Balance: `) + import_chalk.default.cyan(wallet.xlmBalance + " XLM"));
|
|
504
476
|
if (parseFloat(wallet.xlmBalance) === 0 && network === "testnet") {
|
|
505
477
|
console.log(import_chalk.default.yellow("\nAccount not funded. Run: agentmarket fund"));
|
|
506
478
|
}
|
|
@@ -535,8 +507,6 @@ program.command("fund").description("Fund testnet account using Friendbot").acti
|
|
|
535
507
|
if (wallet) {
|
|
536
508
|
console.log(import_chalk.default.bold(` XLM Balance: `) + wallet.xlmBalance + " XLM");
|
|
537
509
|
}
|
|
538
|
-
console.log(import_chalk.default.yellow("\nNote: You also need testnet USDC to make API calls."));
|
|
539
|
-
console.log(import_chalk.default.dim(" Get testnet USDC from: https://laboratory.stellar.org"));
|
|
540
510
|
} else {
|
|
541
511
|
spinner.fail("Failed to fund account");
|
|
542
512
|
}
|
|
@@ -557,12 +527,11 @@ program.command("balance").alias("bal").description("Check wallet balance").acti
|
|
|
557
527
|
console.log(import_chalk.default.bold(" Network: ") + wallet.network);
|
|
558
528
|
console.log(import_chalk.default.bold(" Address: ") + wallet.publicKey);
|
|
559
529
|
console.log(import_chalk.default.bold(" XLM: ") + import_chalk.default.cyan(wallet.xlmBalance + " XLM"));
|
|
560
|
-
console.log(import_chalk.default.bold(" USDC: ") + import_chalk.default.green(wallet.usdcBalance + " USDC"));
|
|
561
530
|
} else {
|
|
562
531
|
spinner.fail("Failed to fetch balance");
|
|
563
532
|
}
|
|
564
533
|
});
|
|
565
|
-
program.command("list").alias("ls").description("List available APIs").option("-c, --category <category>", "Filter by category
|
|
534
|
+
program.command("list").alias("ls").description("List available APIs").option("-c, --category <category>", "Filter by category").action(async (options) => {
|
|
566
535
|
const config2 = loadConfig();
|
|
567
536
|
await refreshRegistry(config2.marketplaceUrl);
|
|
568
537
|
const apis = listApis(options.category);
|
|
@@ -584,15 +553,15 @@ program.command("list").alias("ls").description("List available APIs").option("-
|
|
|
584
553
|
console.log(import_chalk.default.bold.blue(`
|
|
585
554
|
${category}`));
|
|
586
555
|
for (const api of categoryApis) {
|
|
587
|
-
const price = import_chalk.default.green(
|
|
588
|
-
console.log(` ${import_chalk.default.bold(api.slug.padEnd(
|
|
556
|
+
const price = import_chalk.default.green(`${api.priceXlm} XLM`);
|
|
557
|
+
console.log(` ${import_chalk.default.bold(api.slug.padEnd(20))} ${price.padEnd(15)} ${import_chalk.default.dim(api.description)}`);
|
|
589
558
|
}
|
|
590
559
|
}
|
|
591
560
|
console.log(import_chalk.default.dim("\n\u2500".repeat(70)));
|
|
592
|
-
console.log(import_chalk.default.dim(` ${apis.length} APIs available | Prices in
|
|
561
|
+
console.log(import_chalk.default.dim(` ${apis.length} APIs available | Prices in XLM per call
|
|
593
562
|
`));
|
|
594
563
|
});
|
|
595
|
-
program.command("call <api>").description("Call an API with x402 payment").option("-p, --params <json>", "Parameters as JSON string").option("--
|
|
564
|
+
program.command("call <api>").description("Call an API with x402 payment").option("-p, --params <json>", "Parameters as JSON string").option("--symbol <symbol>", "Stock symbol (for stock-analyst/trading-advisor)").option("--dry-run", "Show what would be called without making payment").action(async (apiSlug, options) => {
|
|
596
565
|
const config2 = loadConfig();
|
|
597
566
|
await refreshRegistry(config2.marketplaceUrl);
|
|
598
567
|
if (!config2.secretKey) {
|
|
@@ -614,19 +583,13 @@ program.command("call <api>").description("Call an API with x402 payment").optio
|
|
|
614
583
|
process.exit(1);
|
|
615
584
|
}
|
|
616
585
|
} else {
|
|
617
|
-
if (options.
|
|
618
|
-
if (options.topic) params.topic = options.topic;
|
|
619
|
-
if (options.from) params.from = options.from;
|
|
620
|
-
if (options.to) params.to = options.to;
|
|
621
|
-
if (options.amount) params.amount = parseFloat(options.amount);
|
|
622
|
-
if (options.ip) params.ip = options.ip;
|
|
623
|
-
if (options.prompt) params.prompt = options.prompt;
|
|
586
|
+
if (options.symbol) params.symbol = options.symbol;
|
|
624
587
|
}
|
|
625
588
|
console.log(import_chalk.default.bold(`
|
|
626
|
-
Calling ${api.name}
|
|
589
|
+
Calling ${api.name}
|
|
627
590
|
`));
|
|
628
591
|
console.log(import_chalk.default.dim(` Endpoint: ${api.endpoint}`));
|
|
629
|
-
console.log(import_chalk.default.dim(` Price: ${api.
|
|
592
|
+
console.log(import_chalk.default.dim(` Price: ${api.priceXlm} XLM`));
|
|
630
593
|
console.log(import_chalk.default.dim(` Params: ${JSON.stringify(params)}`));
|
|
631
594
|
if (options.dryRun) {
|
|
632
595
|
console.log(import_chalk.default.yellow("\n [DRY RUN] No payment made"));
|
|
@@ -634,7 +597,7 @@ Calling ${api.name} API
|
|
|
634
597
|
}
|
|
635
598
|
const stellarClient = new StellarClient(config2.stellarNetwork);
|
|
636
599
|
stellarClient.setSecretKey(config2.secretKey);
|
|
637
|
-
const spinner = (0, import_ora.default)("
|
|
600
|
+
const spinner = (0, import_ora.default)("Paying XLM and calling API...").start();
|
|
638
601
|
const result = await callApi(apiSlug, params, stellarClient);
|
|
639
602
|
if (result.success) {
|
|
640
603
|
spinner.succeed("API call successful!");
|
|
@@ -644,7 +607,7 @@ Calling ${api.name} API
|
|
|
644
607
|
console.log(import_chalk.default.dim(` Explorer: ${explorerUrl}`));
|
|
645
608
|
}
|
|
646
609
|
if (result.amountPaid) {
|
|
647
|
-
console.log(import_chalk.default.dim(` Paid: ${result.amountPaid}
|
|
610
|
+
console.log(import_chalk.default.dim(` Paid: ${result.amountPaid} XLM`));
|
|
648
611
|
}
|
|
649
612
|
if (result.latencyMs) {
|
|
650
613
|
console.log(import_chalk.default.dim(` Latency: ${result.latencyMs}ms`));
|
|
@@ -668,26 +631,26 @@ program.command("history").alias("hist").description("Show call history").option
|
|
|
668
631
|
console.log(import_chalk.default.dim(" No calls made yet"));
|
|
669
632
|
return;
|
|
670
633
|
}
|
|
671
|
-
console.log(import_chalk.default.dim(" " + "Time".padEnd(20) + "API".padEnd(
|
|
634
|
+
console.log(import_chalk.default.dim(" " + "Time".padEnd(20) + "API".padEnd(20) + "Amount".padEnd(12) + "Transaction"));
|
|
672
635
|
console.log(import_chalk.default.dim(" " + "\u2500".repeat(70)));
|
|
673
636
|
for (const call of recent) {
|
|
674
637
|
const time = new Date(call.timestamp).toLocaleString();
|
|
675
|
-
const amount = import_chalk.default.green(
|
|
638
|
+
const amount = import_chalk.default.green(`${call.amount.toFixed(1)} XLM`);
|
|
676
639
|
const txShort = call.txHash.substring(0, 16) + "...";
|
|
677
|
-
console.log(` ${time.padEnd(20)} ${call.api.padEnd(
|
|
640
|
+
console.log(` ${time.padEnd(20)} ${call.api.padEnd(20)} ${amount.padEnd(12)} ${import_chalk.default.dim(txShort)}`);
|
|
678
641
|
}
|
|
679
642
|
const totalSpent = history.calls.reduce((sum, c) => sum + c.amount, 0);
|
|
680
643
|
console.log(import_chalk.default.dim(" " + "\u2500".repeat(70)));
|
|
681
|
-
console.log(import_chalk.default.bold(` Total: ${history.calls.length} calls, ${import_chalk.default.green(
|
|
644
|
+
console.log(import_chalk.default.bold(` Total: ${history.calls.length} calls, ${import_chalk.default.green(totalSpent.toFixed(4) + " XLM")} spent`));
|
|
682
645
|
});
|
|
683
|
-
program.command("config").description("View or update configuration").option("--show", "Show current config").option("--network <network>", "Set network (testnet/mainnet)").option("--budget <amount>", "Set budget limit (
|
|
646
|
+
program.command("config").description("View or update configuration").option("--show", "Show current config").option("--network <network>", "Set network (testnet/mainnet)").option("--budget <amount>", "Set budget limit (XLM)").option("--marketplace <url>", "Set marketplace URL").action((options) => {
|
|
684
647
|
const config2 = loadConfig();
|
|
685
|
-
if (options.show ||
|
|
648
|
+
if (options.show || !options.network && !options.budget && !options.marketplace) {
|
|
686
649
|
console.log(import_chalk.default.bold("\nConfiguration\n"));
|
|
687
650
|
console.log(import_chalk.default.dim(` Config file: ${getConfigPath()}`));
|
|
688
651
|
console.log("");
|
|
689
652
|
console.log(import_chalk.default.bold(" Network: ") + config2.stellarNetwork);
|
|
690
|
-
console.log(import_chalk.default.bold(" Budget: ") + config2.budgetLimit + "
|
|
653
|
+
console.log(import_chalk.default.bold(" Budget: ") + config2.budgetLimit + " XLM");
|
|
691
654
|
console.log(import_chalk.default.bold(" Marketplace: ") + config2.marketplaceUrl);
|
|
692
655
|
console.log(import_chalk.default.bold(" Public Key: ") + (config2.publicKey || "Not set"));
|
|
693
656
|
console.log(import_chalk.default.bold(" Secret Key: ") + (config2.secretKey ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "Not set"));
|
|
@@ -727,31 +690,22 @@ ${api.name}
|
|
|
727
690
|
console.log(import_chalk.default.bold(" Slug: ") + api.slug);
|
|
728
691
|
console.log(import_chalk.default.bold(" Description: ") + api.description);
|
|
729
692
|
console.log(import_chalk.default.bold(" Category: ") + api.category);
|
|
730
|
-
console.log(import_chalk.default.bold(" Price: ") + import_chalk.default.green(
|
|
693
|
+
console.log(import_chalk.default.bold(" Price: ") + import_chalk.default.green(`${api.priceXlm} XLM`));
|
|
731
694
|
console.log(import_chalk.default.bold(" Provider: ") + api.provider);
|
|
732
695
|
console.log(import_chalk.default.bold(" Endpoint: ") + api.endpoint);
|
|
696
|
+
if (api.params?.length) {
|
|
697
|
+
console.log(import_chalk.default.bold("\n Parameters:\n"));
|
|
698
|
+
for (const p of api.params) {
|
|
699
|
+
const req = p.required ? import_chalk.default.red("required") : import_chalk.default.dim("optional");
|
|
700
|
+
console.log(` ${import_chalk.default.bold(p.name.padEnd(15))} ${p.type.padEnd(10)} ${req.padEnd(18)} ${import_chalk.default.dim(p.description)}`);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
const exampleParams = api.params?.filter((p) => p.required).map((p) => `"${p.name}": "<${p.type}>"`).join(", ") ?? "";
|
|
733
704
|
console.log(import_chalk.default.bold("\n Example:\n"));
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
case "air-quality":
|
|
739
|
-
console.log(import_chalk.default.cyan(' agentmarket call air-quality --city "Delhi"'));
|
|
740
|
-
break;
|
|
741
|
-
case "news":
|
|
742
|
-
console.log(import_chalk.default.cyan(' agentmarket call news --topic "technology"'));
|
|
743
|
-
break;
|
|
744
|
-
case "currency":
|
|
745
|
-
console.log(import_chalk.default.cyan(" agentmarket call currency --from USD --to EUR --amount 100"));
|
|
746
|
-
break;
|
|
747
|
-
case "geolocation":
|
|
748
|
-
console.log(import_chalk.default.cyan(' agentmarket call geolocation --ip "8.8.8.8"'));
|
|
749
|
-
break;
|
|
750
|
-
case "ai":
|
|
751
|
-
console.log(import_chalk.default.cyan(' agentmarket call ai --prompt "Explain quantum computing"'));
|
|
752
|
-
break;
|
|
753
|
-
default:
|
|
754
|
-
console.log(import_chalk.default.cyan(` agentmarket call ${api.slug} -p '{"key": "value"}'`));
|
|
705
|
+
if (exampleParams) {
|
|
706
|
+
console.log(import_chalk.default.cyan(` agentmarket call ${api.slug} -p '{${exampleParams}}'`));
|
|
707
|
+
} else {
|
|
708
|
+
console.log(import_chalk.default.cyan(` agentmarket call ${api.slug}`));
|
|
755
709
|
}
|
|
756
710
|
});
|
|
757
711
|
program.parse();
|
package/dist/index.d.ts
CHANGED
|
@@ -9,21 +9,27 @@ interface Config {
|
|
|
9
9
|
budgetLimit: number;
|
|
10
10
|
contractId?: string;
|
|
11
11
|
}
|
|
12
|
+
interface ApiParam {
|
|
13
|
+
name: string;
|
|
14
|
+
type: string;
|
|
15
|
+
required: boolean;
|
|
16
|
+
description: string;
|
|
17
|
+
}
|
|
12
18
|
interface ApiInfo {
|
|
13
19
|
name: string;
|
|
14
20
|
slug: string;
|
|
15
21
|
description: string;
|
|
16
22
|
category: string;
|
|
17
|
-
|
|
23
|
+
priceXlm: number;
|
|
18
24
|
endpoint: string;
|
|
19
25
|
method: 'GET' | 'POST';
|
|
20
26
|
provider: string;
|
|
27
|
+
params?: ApiParam[];
|
|
21
28
|
}
|
|
22
29
|
interface WalletInfo {
|
|
23
30
|
publicKey: string;
|
|
24
31
|
network: 'testnet' | 'mainnet';
|
|
25
32
|
xlmBalance: string;
|
|
26
|
-
usdcBalance: string;
|
|
27
33
|
}
|
|
28
34
|
interface CallResult {
|
|
29
35
|
success: boolean;
|
|
@@ -50,6 +56,7 @@ interface TransactionRecord {
|
|
|
50
56
|
|
|
51
57
|
/**
|
|
52
58
|
* AgentMarket CLI - Stellar Client
|
|
59
|
+
* Native XLM payments only
|
|
53
60
|
*/
|
|
54
61
|
|
|
55
62
|
declare class StellarClient {
|
|
@@ -61,6 +68,7 @@ declare class StellarClient {
|
|
|
61
68
|
getPublicKey(): string | null;
|
|
62
69
|
getWalletInfo(): Promise<WalletInfo | null>;
|
|
63
70
|
fundTestnetAccount(): Promise<string | null>;
|
|
71
|
+
/** Send native XLM payment */
|
|
64
72
|
sendPayment(destination: string, amount: string, memo?: string): Promise<{
|
|
65
73
|
txHash: string;
|
|
66
74
|
success: boolean;
|
|
@@ -74,6 +82,7 @@ declare class StellarClient {
|
|
|
74
82
|
|
|
75
83
|
/**
|
|
76
84
|
* AgentMarket CLI - API Client
|
|
85
|
+
* Native XLM payments on Stellar mainnet
|
|
77
86
|
*/
|
|
78
87
|
|
|
79
88
|
declare function listApis(category?: string): ApiInfo[];
|
|
@@ -97,4 +106,4 @@ declare function appendHistory(call: {
|
|
|
97
106
|
txHash: string;
|
|
98
107
|
}): void;
|
|
99
108
|
|
|
100
|
-
export { type ApiInfo, type BudgetStatus, type CallResult, type Config, StellarClient, type TransactionRecord, type WalletInfo, appendHistory, callApi, getApiInfo, listApis, loadConfig, loadHistory, saveConfig };
|
|
109
|
+
export { type ApiInfo, type ApiParam, type BudgetStatus, type CallResult, type Config, StellarClient, type TransactionRecord, type WalletInfo, appendHistory, callApi, getApiInfo, listApis, loadConfig, loadHistory, saveConfig };
|
package/dist/index.js
CHANGED
|
@@ -46,22 +46,18 @@ var StellarSdk = __toESM(require("@stellar/stellar-sdk"));
|
|
|
46
46
|
var NETWORKS = {
|
|
47
47
|
testnet: {
|
|
48
48
|
networkPassphrase: StellarSdk.Networks.TESTNET,
|
|
49
|
-
horizonUrl: "https://horizon-testnet.stellar.org"
|
|
50
|
-
sorobanUrl: "https://soroban-testnet.stellar.org"
|
|
49
|
+
horizonUrl: "https://horizon-testnet.stellar.org"
|
|
51
50
|
},
|
|
52
51
|
mainnet: {
|
|
53
52
|
networkPassphrase: StellarSdk.Networks.PUBLIC,
|
|
54
|
-
horizonUrl: "https://horizon.stellar.org"
|
|
55
|
-
sorobanUrl: "https://mainnet.stellar.org"
|
|
53
|
+
horizonUrl: "https://horizon.stellar.org"
|
|
56
54
|
}
|
|
57
55
|
};
|
|
58
|
-
var USDC_TESTNET_ISSUER = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5";
|
|
59
|
-
var USDC_MAINNET_ISSUER = "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN";
|
|
60
56
|
var StellarClient = class {
|
|
61
57
|
network;
|
|
62
58
|
server;
|
|
63
59
|
keypair = null;
|
|
64
|
-
constructor(network = "
|
|
60
|
+
constructor(network = "mainnet") {
|
|
65
61
|
this.network = network;
|
|
66
62
|
const config = NETWORKS[network];
|
|
67
63
|
this.server = new StellarSdk.Horizon.Server(config.horizonUrl);
|
|
@@ -77,27 +73,21 @@ var StellarClient = class {
|
|
|
77
73
|
try {
|
|
78
74
|
const account = await this.server.loadAccount(this.keypair.publicKey());
|
|
79
75
|
let xlmBalance = "0";
|
|
80
|
-
let usdcBalance = "0";
|
|
81
|
-
const usdcIssuer = this.network === "testnet" ? USDC_TESTNET_ISSUER : USDC_MAINNET_ISSUER;
|
|
82
76
|
for (const balance of account.balances) {
|
|
83
77
|
if (balance.asset_type === "native") {
|
|
84
78
|
xlmBalance = balance.balance;
|
|
85
|
-
} else if (balance.asset_type !== "liquidity_pool_shares" && balance.asset_code === "USDC" && balance.asset_issuer === usdcIssuer) {
|
|
86
|
-
usdcBalance = balance.balance;
|
|
87
79
|
}
|
|
88
80
|
}
|
|
89
81
|
return {
|
|
90
82
|
publicKey: this.keypair.publicKey(),
|
|
91
83
|
network: this.network,
|
|
92
|
-
xlmBalance
|
|
93
|
-
usdcBalance
|
|
84
|
+
xlmBalance
|
|
94
85
|
};
|
|
95
86
|
} catch (error) {
|
|
96
87
|
return {
|
|
97
88
|
publicKey: this.keypair.publicKey(),
|
|
98
89
|
network: this.network,
|
|
99
|
-
xlmBalance: "0"
|
|
100
|
-
usdcBalance: "0"
|
|
90
|
+
xlmBalance: "0"
|
|
101
91
|
};
|
|
102
92
|
}
|
|
103
93
|
}
|
|
@@ -114,26 +104,25 @@ var StellarClient = class {
|
|
|
114
104
|
}
|
|
115
105
|
return null;
|
|
116
106
|
}
|
|
107
|
+
/** Send native XLM payment */
|
|
117
108
|
async sendPayment(destination, amount, memo) {
|
|
118
109
|
if (!this.keypair) return null;
|
|
119
110
|
try {
|
|
120
111
|
const account = await this.server.loadAccount(this.keypair.publicKey());
|
|
121
|
-
const
|
|
122
|
-
const usdcAsset = new StellarSdk.Asset("USDC", usdcIssuer);
|
|
123
|
-
const transaction = new StellarSdk.TransactionBuilder(account, {
|
|
112
|
+
const transactionBuilder = new StellarSdk.TransactionBuilder(account, {
|
|
124
113
|
fee: StellarSdk.BASE_FEE,
|
|
125
114
|
networkPassphrase: NETWORKS[this.network].networkPassphrase
|
|
126
115
|
}).addOperation(
|
|
127
116
|
StellarSdk.Operation.payment({
|
|
128
117
|
destination,
|
|
129
|
-
asset:
|
|
118
|
+
asset: StellarSdk.Asset.native(),
|
|
130
119
|
amount
|
|
131
120
|
})
|
|
132
121
|
).setTimeout(30);
|
|
133
122
|
if (memo) {
|
|
134
|
-
|
|
123
|
+
transactionBuilder.addMemo(StellarSdk.Memo.text(memo.substring(0, 28)));
|
|
135
124
|
}
|
|
136
|
-
const builtTx =
|
|
125
|
+
const builtTx = transactionBuilder.build();
|
|
137
126
|
builtTx.sign(this.keypair);
|
|
138
127
|
const result = await this.server.submitTransaction(builtTx);
|
|
139
128
|
return {
|
|
@@ -141,8 +130,10 @@ var StellarClient = class {
|
|
|
141
130
|
success: true
|
|
142
131
|
};
|
|
143
132
|
} catch (error) {
|
|
144
|
-
|
|
145
|
-
|
|
133
|
+
const axiosLike = error;
|
|
134
|
+
const resultCodes = axiosLike?.response?.data?.extras?.result_codes;
|
|
135
|
+
const detail = resultCodes ? `Horizon rejected tx: ${JSON.stringify(resultCodes)}` : error instanceof Error ? error.message : "Unknown error";
|
|
136
|
+
throw new Error(detail);
|
|
146
137
|
}
|
|
147
138
|
}
|
|
148
139
|
async verifyTransaction(txHash) {
|
|
@@ -179,11 +170,11 @@ var CONTRACTS = {
|
|
|
179
170
|
}
|
|
180
171
|
};
|
|
181
172
|
var DEFAULT_CONFIG = {
|
|
182
|
-
stellarNetwork: "
|
|
183
|
-
marketplaceUrl: "https://
|
|
173
|
+
stellarNetwork: "mainnet",
|
|
174
|
+
marketplaceUrl: "https://steller-web.vercel.app",
|
|
184
175
|
budgetLimit: 10,
|
|
185
|
-
// 10
|
|
186
|
-
contractId: CONTRACTS.
|
|
176
|
+
// 10 XLM default
|
|
177
|
+
contractId: CONTRACTS.mainnet.budgetEnforcer
|
|
187
178
|
};
|
|
188
179
|
function ensureConfigDir() {
|
|
189
180
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
@@ -233,64 +224,24 @@ function appendHistory(call) {
|
|
|
233
224
|
var REGISTRY_TTL_MS = 60 * 60 * 1e3;
|
|
234
225
|
var FALLBACK_REGISTRY = [
|
|
235
226
|
{
|
|
236
|
-
name: "
|
|
237
|
-
slug: "
|
|
238
|
-
description: "
|
|
239
|
-
category: "Data",
|
|
240
|
-
priceUsdc: 1e-3,
|
|
241
|
-
endpoint: "/api/proxy/weather",
|
|
242
|
-
method: "GET",
|
|
243
|
-
provider: "AgentMarket"
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
name: "Air Quality",
|
|
247
|
-
slug: "air-quality",
|
|
248
|
-
description: "Get real-time air quality index and pollution data",
|
|
249
|
-
category: "Data",
|
|
250
|
-
priceUsdc: 1e-3,
|
|
251
|
-
endpoint: "/api/proxy/air-quality",
|
|
252
|
-
method: "GET",
|
|
253
|
-
provider: "AgentMarket"
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
name: "News",
|
|
257
|
-
slug: "news",
|
|
258
|
-
description: "Fetch latest news headlines by topic",
|
|
259
|
-
category: "Data",
|
|
260
|
-
priceUsdc: 2e-3,
|
|
261
|
-
endpoint: "/api/proxy/news",
|
|
262
|
-
method: "GET",
|
|
263
|
-
provider: "AgentMarket"
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
name: "Currency Exchange",
|
|
267
|
-
slug: "currency",
|
|
268
|
-
description: "Convert between currencies with live rates",
|
|
227
|
+
name: "Stock Analyst",
|
|
228
|
+
slug: "stock-analyst",
|
|
229
|
+
description: "Live Yahoo Finance data + Gemini sentiment analysis",
|
|
269
230
|
category: "Finance",
|
|
270
|
-
|
|
271
|
-
endpoint: "/api/proxy/
|
|
231
|
+
priceXlm: 0.1,
|
|
232
|
+
endpoint: "/api/proxy/stock-analyst",
|
|
272
233
|
method: "GET",
|
|
273
234
|
provider: "AgentMarket"
|
|
274
235
|
},
|
|
275
236
|
{
|
|
276
|
-
name: "
|
|
277
|
-
slug: "
|
|
278
|
-
description: "
|
|
279
|
-
category: "
|
|
280
|
-
|
|
281
|
-
endpoint: "/api/proxy/
|
|
237
|
+
name: "Trading Advisor",
|
|
238
|
+
slug: "trading-advisor",
|
|
239
|
+
description: "Two-stage Gemini reasoning \u2192 BUY/HOLD/SELL with targets",
|
|
240
|
+
category: "Finance",
|
|
241
|
+
priceXlm: 0.5,
|
|
242
|
+
endpoint: "/api/proxy/trading-advisor",
|
|
282
243
|
method: "GET",
|
|
283
244
|
provider: "AgentMarket"
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
name: "AI Inference",
|
|
287
|
-
slug: "ai",
|
|
288
|
-
description: "Run AI inference queries (GPT, Claude)",
|
|
289
|
-
category: "AI",
|
|
290
|
-
priceUsdc: 5e-3,
|
|
291
|
-
endpoint: "/api/proxy/ai",
|
|
292
|
-
method: "POST",
|
|
293
|
-
provider: "AgentMarket"
|
|
294
245
|
}
|
|
295
246
|
];
|
|
296
247
|
var _registry = [...FALLBACK_REGISTRY];
|
|
@@ -335,13 +286,25 @@ async function callApi(slug, params, stellarClient) {
|
|
|
335
286
|
if (!wallet) {
|
|
336
287
|
return { success: false, error: "Wallet not configured. Run: agentmarket init" };
|
|
337
288
|
}
|
|
338
|
-
const
|
|
339
|
-
|
|
289
|
+
const xlmBalance = parseFloat(wallet.xlmBalance);
|
|
290
|
+
const STELLAR_MIN_RESERVE = 1;
|
|
291
|
+
const spendable = Math.max(0, xlmBalance - STELLAR_MIN_RESERVE);
|
|
292
|
+
if (spendable < api.priceXlm) {
|
|
340
293
|
return {
|
|
341
294
|
success: false,
|
|
342
|
-
error: `Insufficient
|
|
295
|
+
error: `Insufficient spendable XLM. Need ${api.priceXlm} XLM (balance: ${xlmBalance} XLM, ${STELLAR_MIN_RESERVE} XLM reserved by Stellar \u2014 spendable: ${spendable.toFixed(4)} XLM)`
|
|
343
296
|
};
|
|
344
297
|
}
|
|
298
|
+
if (api.params?.length) {
|
|
299
|
+
const missing = api.params.filter((p) => p.required && (params[p.name] === void 0 || params[p.name] === null || params[p.name] === "")).map((p) => ` --${p.name} (${p.type}): ${p.description}`);
|
|
300
|
+
if (missing.length > 0) {
|
|
301
|
+
return {
|
|
302
|
+
success: false,
|
|
303
|
+
error: `Missing required params \u2014 no payment made:
|
|
304
|
+
${missing.join("\n")}`
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
}
|
|
345
308
|
const baseUrl = config.marketplaceUrl;
|
|
346
309
|
const initialRequest = buildRequest(api, baseUrl, params);
|
|
347
310
|
try {
|
|
@@ -354,7 +317,12 @@ async function callApi(slug, params, stellarClient) {
|
|
|
354
317
|
const recipient = paymentDetails.payment.recipient;
|
|
355
318
|
const amount = paymentDetails.payment.amount;
|
|
356
319
|
const memo = paymentDetails.payment?.memo || `am:${slug}:${Date.now()}`;
|
|
357
|
-
|
|
320
|
+
let paymentResult;
|
|
321
|
+
try {
|
|
322
|
+
paymentResult = await stellarClient.sendPayment(recipient, amount, memo);
|
|
323
|
+
} catch (err) {
|
|
324
|
+
return { success: false, error: err instanceof Error ? err.message : "Payment failed" };
|
|
325
|
+
}
|
|
358
326
|
if (!paymentResult?.success) {
|
|
359
327
|
return { success: false, error: "Payment failed" };
|
|
360
328
|
}
|
|
@@ -374,7 +342,7 @@ async function callApi(slug, params, stellarClient) {
|
|
|
374
342
|
success: false,
|
|
375
343
|
error: `API call failed: ${retryResponse.status}`,
|
|
376
344
|
txHash: paymentResult.txHash,
|
|
377
|
-
amountPaid: api.
|
|
345
|
+
amountPaid: api.priceXlm
|
|
378
346
|
};
|
|
379
347
|
}
|
|
380
348
|
const data = await retryResponse.json();
|
|
@@ -382,10 +350,10 @@ async function callApi(slug, params, stellarClient) {
|
|
|
382
350
|
appendHistory({
|
|
383
351
|
api: slug,
|
|
384
352
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
385
|
-
amount: api.
|
|
353
|
+
amount: api.priceXlm,
|
|
386
354
|
txHash: paymentResult.txHash
|
|
387
355
|
});
|
|
388
|
-
return { success: true, data, txHash: paymentResult.txHash, amountPaid: api.
|
|
356
|
+
return { success: true, data, txHash: paymentResult.txHash, amountPaid: api.priceXlm, latencyMs };
|
|
389
357
|
}
|
|
390
358
|
if (initialResponse.ok) {
|
|
391
359
|
const data = await initialResponse.json();
|