@paynodelabs/paynode-402-cli 2.5.1 → 2.6.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.
@@ -63,7 +63,7 @@ export interface RawCatalogApiItem {
63
63
 
64
64
  function normalizeCatalogItem(raw: RawCatalogApiItem): CatalogApiItem {
65
65
  return {
66
- id: raw.id || raw.api_id || '',
66
+ id: raw.api_id || raw.id?.replace(/-(testnet|mainnet)$/, '') || '',
67
67
  name: raw.name || raw.title || raw.api_name || raw.api_id || 'unnamed',
68
68
  description: raw.description,
69
69
  tags: Array.isArray(raw.tags) ? raw.tags : [],
@@ -147,7 +147,12 @@ export class MarketplaceClient {
147
147
  if (network) params.set('network', network);
148
148
  const query = params.toString();
149
149
  const path = `/api/v1/paid-apis/${encodeURIComponent(apiId)}${query ? `?${query}` : ''}`;
150
- const raw = await this.request<any>(path);
150
+ const raw = await this.request<any>(path, {
151
+ method: 'POST',
152
+ headers: {
153
+ 'X-PayNode-Discovery': 'true'
154
+ }
155
+ });
151
156
  return normalizeCatalogItem(raw);
152
157
  }
153
158
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paynodelabs/paynode-402-cli",
3
- "version": "2.5.1",
3
+ "version": "2.6.0",
4
4
  "description": "The official command-line interface for the PayNode protocol. Designed for AI Agents to execute stateless micro-payments via HTTP 402.",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -37,4 +37,4 @@
37
37
  "url": "https://github.com/PayNodeLabs/paynode-402-cli/issues"
38
38
  },
39
39
  "homepage": "https://github.com/PayNodeLabs/paynode-402-cli#readme"
40
- }
40
+ }
package/utils.ts CHANGED
@@ -16,15 +16,33 @@ if (!process.env.CLIENT_PRIVATE_KEY) {
16
16
  /**
17
17
  * Centralized Configuration Loader
18
18
  * [SECURITY] Consolidates environment variable access for better auditing.
19
+ * Priority: 1. System Environment Variable (B) | 2. XDG Config File (A)
19
20
  */
20
- export const GLOBAL_CONFIG = {
21
- MARKETPLACE_URL: process.env.PAYNODE_MARKET_URL || 'https://mk.paynode.dev',
22
- PRIVATE_KEY: process.env.CLIENT_PRIVATE_KEY,
23
- CUSTOM_ROUTER: process.env.CUSTOM_ROUTER_ADDRESS,
24
- CUSTOM_USDC: process.env.CUSTOM_USDC_ADDRESS,
25
- RPC_URL_OVERRIDE: process.env.PAYNODE_RPC_URL || process.env.RPC_URL,
26
- RPC_TIMEOUT: Number(process.env.PAYNODE_RPC_TIMEOUT) || 15_000
27
- };
21
+ function loadConfig() {
22
+ const home = process.env.HOME || process.env.USERPROFILE || '';
23
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME || join(home, '.config');
24
+ const xdgConfigPath = join(xdgConfigHome, 'paynode', 'config.json');
25
+
26
+ let localConfig: Record<string, string> = {};
27
+ if (fs.existsSync(xdgConfigPath)) {
28
+ try {
29
+ localConfig = JSON.parse(fs.readFileSync(xdgConfigPath, 'utf8'));
30
+ } catch { /* ignore invalid json */ }
31
+ }
32
+
33
+ return {
34
+ MARKETPLACE_URL: process.env.PAYNODE_MARKET_URL || localConfig.PAYNODE_MARKET_URL || 'https://mk.paynode.dev',
35
+ PRIVATE_KEY: process.env.CLIENT_PRIVATE_KEY || localConfig.CLIENT_PRIVATE_KEY,
36
+ CUSTOM_ROUTER: process.env.CUSTOM_ROUTER_ADDRESS || localConfig.CUSTOM_ROUTER_ADDRESS,
37
+ CUSTOM_USDC: process.env.CUSTOM_USDC_ADDRESS || localConfig.CUSTOM_USDC_ADDRESS,
38
+ RPC_URL_OVERRIDE: process.env.PAYNODE_RPC_URL || process.env.RPC_URL || localConfig.PAYNODE_RPC_URL,
39
+ RPC_TIMEOUT: Number(process.env.PAYNODE_RPC_TIMEOUT || localConfig.PAYNODE_RPC_TIMEOUT) || 15_000,
40
+ configSource: process.env.CLIENT_PRIVATE_KEY ? 'env' : (localConfig.CLIENT_PRIVATE_KEY ? 'file' : 'missing'),
41
+ configFilePath: xdgConfigPath
42
+ };
43
+ }
44
+
45
+ export const GLOBAL_CONFIG = loadConfig();
28
46
 
29
47
  /**
30
48
  * Skill version for JSON output metadata.
@@ -240,7 +258,8 @@ export function cleanupOldTasks(taskDir: string, maxAgeSeconds: number): number
240
258
  export function getPrivateKey(isJson: boolean): string {
241
259
  const pk: string | undefined = GLOBAL_CONFIG.PRIVATE_KEY;
242
260
  if (!pk || typeof pk !== 'string') {
243
- reportError('CLIENT_PRIVATE_KEY not found in environment. Please set it as a system environment variable.', isJson, EXIT_CODES.AUTH_FAILURE);
261
+ const msg = `CLIENT_PRIVATE_KEY not found. Please set environment (B) or create config file (A) at: ${GLOBAL_CONFIG.configFilePath}`;
262
+ reportError(msg, isJson, EXIT_CODES.AUTH_FAILURE);
244
263
  }
245
264
  const pkRegex = /^0x[0-9a-fA-F]{64}$/;
246
265
  if (!pkRegex.test(pk)) {