@relai-fi/x402 0.5.24 → 0.5.26

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 CHANGED
@@ -300,6 +300,13 @@ import {
300
300
  fromAtomicUnits,
301
301
  } from '@relai-fi/x402/utils';
302
302
 
303
+ // Management API — create/manage APIs, pricing, analytics, agent bootstrap
304
+ import {
305
+ createManagementClient,
306
+ bootstrapAgentKeySolana,
307
+ bootstrapAgentKeyEvm,
308
+ } from '@relai-fi/x402/management';
309
+
303
310
  // Types & constants
304
311
  import {
305
312
  RELAI_NETWORKS,
@@ -461,6 +468,82 @@ app.get('/api/solana-data', relai.protect({
461
468
 
462
469
  ---
463
470
 
471
+ ## Management API
472
+
473
+ Programmatically create and manage monetised APIs, update pricing, and read analytics. Designed for agents and CI/CD — no browser needed.
474
+
475
+ ```typescript
476
+ import { createManagementClient } from '@relai-fi/x402/management';
477
+
478
+ const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });
479
+
480
+ // Create a monetised API
481
+ const api = await mgmt.createApi({
482
+ name: 'My ML API',
483
+ baseUrl: 'https://inference.example.com',
484
+ merchantWallet: '0xYourWallet',
485
+ network: 'base',
486
+ endpoints: [
487
+ { path: '/v1/predict', method: 'post', usdPrice: 0.05 },
488
+ { path: '/v1/status', method: 'get', usdPrice: 0.001 },
489
+ ],
490
+ });
491
+
492
+ // List / get / update / delete
493
+ const all = await mgmt.listApis();
494
+ const one = await mgmt.getApi(api.apiId);
495
+ await mgmt.updateApi(api.apiId, { description: 'Updated description' });
496
+ await mgmt.deleteApi(api.apiId);
497
+
498
+ // Pricing
499
+ await mgmt.setPricing(api.apiId, [{ path: '/v1/predict', method: 'post', usdPrice: 0.10 }]);
500
+ const pricing = await mgmt.getPricing(api.apiId);
501
+
502
+ // Analytics
503
+ const stats = await mgmt.getStats(api.apiId);
504
+ const payments = await mgmt.getPayments(api.apiId, { limit: 20, from: '2025-01-01' });
505
+ const logs = await mgmt.getLogs(api.apiId, { limit: 20 });
506
+ ```
507
+
508
+ ### Agent self-setup (autonomous key provisioning)
509
+
510
+ Agents can provision their own service key with zero human involvement — no dashboard, no JWT, no copy-paste. Run once and store the key.
511
+
512
+ ```typescript
513
+ import { bootstrapAgentKeySolana, bootstrapAgentKeyEvm } from '@relai-fi/x402/management';
514
+ import { Keypair } from '@solana/web3.js';
515
+
516
+ // Solana agent
517
+ const keypair = Keypair.fromSecretKey(Buffer.from(process.env.AGENT_PRIVATE_KEY!, 'base64'));
518
+ const { key } = await bootstrapAgentKeySolana(keypair, 'my-agent');
519
+ // → key: "sk_live_..." — store securely, never re-run
520
+
521
+ // EVM agent (ethers.js Wallet)
522
+ import { ethers } from 'ethers';
523
+ const wallet = new ethers.Wallet(process.env.AGENT_PRIVATE_KEY!);
524
+ const { key: evmKey } = await bootstrapAgentKeyEvm(wallet, 'my-evm-agent');
525
+ ```
526
+
527
+ Once you have a service key, combine it with `createX402Client` for a fully autonomous agent:
528
+
529
+ ```typescript
530
+ import { createX402Client } from '@relai-fi/x402/client';
531
+ import { createManagementClient } from '@relai-fi/x402/management';
532
+
533
+ const serviceKey = process.env.RELAI_SERVICE_KEY!;
534
+
535
+ // Pay for APIs
536
+ const client = createX402Client({
537
+ wallets: { solana: agentWallet },
538
+ defaultHeaders: { 'X-Service-Key': serviceKey },
539
+ });
540
+
541
+ // Manage APIs
542
+ const mgmt = createManagementClient({ serviceKey });
543
+ ```
544
+
545
+ ---
546
+
464
547
  ## Utilities
465
548
 
466
549
  ```typescript
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/management.ts
31
+ var management_exports = {};
32
+ __export(management_exports, {
33
+ bootstrapAgentKeyEvm: () => bootstrapAgentKeyEvm,
34
+ bootstrapAgentKeySolana: () => bootstrapAgentKeySolana,
35
+ createManagementClient: () => createManagementClient
36
+ });
37
+ module.exports = __toCommonJS(management_exports);
38
+ var RELAI_API_BASE = "https://api.relai.fi";
39
+ var BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;
40
+ async function bootstrapAgentKeySolana(keypair, label = "agent") {
41
+ const { sign } = await import("tweetnacl");
42
+ const publicKey = keypair.publicKey.toBase58();
43
+ const challengeRes = await fetch(BOOTSTRAP_URL, {
44
+ method: "POST",
45
+ headers: { "Content-Type": "application/json" },
46
+ body: JSON.stringify({ publicKey })
47
+ });
48
+ if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);
49
+ const { message } = await challengeRes.json();
50
+ const msgBytes = new TextEncoder().encode(message);
51
+ const sigBytes = sign.detached(msgBytes, keypair.secretKey);
52
+ const signature = Buffer.from(sigBytes).toString("base64");
53
+ const keyRes = await fetch(BOOTSTRAP_URL, {
54
+ method: "POST",
55
+ headers: { "Content-Type": "application/json" },
56
+ body: JSON.stringify({ publicKey, signature, message, label })
57
+ });
58
+ if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);
59
+ return keyRes.json();
60
+ }
61
+ async function bootstrapAgentKeyEvm(wallet, label = "agent") {
62
+ const publicKey = wallet.address;
63
+ const challengeRes = await fetch(BOOTSTRAP_URL, {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify({ publicKey })
67
+ });
68
+ if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);
69
+ const { message } = await challengeRes.json();
70
+ const signature = await wallet.signMessage(message);
71
+ const keyRes = await fetch(BOOTSTRAP_URL, {
72
+ method: "POST",
73
+ headers: { "Content-Type": "application/json" },
74
+ body: JSON.stringify({ publicKey, signature, message, label })
75
+ });
76
+ if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);
77
+ return keyRes.json();
78
+ }
79
+ function createManagementClient(config) {
80
+ const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\/$/, "");
81
+ const headers = {
82
+ "X-Service-Key": config.serviceKey,
83
+ "Content-Type": "application/json"
84
+ };
85
+ async function req(method, path, body) {
86
+ const res = await fetch(`${base}${path}`, {
87
+ method,
88
+ headers,
89
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {}
90
+ });
91
+ if (!res.ok) {
92
+ const text = await res.text().catch(() => "");
93
+ throw new Error(`[relai-mgmt] ${method} ${path} \u2192 ${res.status}: ${text}`);
94
+ }
95
+ return res.json();
96
+ }
97
+ return {
98
+ // ── APIs ──────────────────────────────────────────────────────────────
99
+ createApi(input) {
100
+ return req("POST", "/v1/apis", input);
101
+ },
102
+ async listApis() {
103
+ const data = await req("GET", "/v1/apis");
104
+ return data.apis;
105
+ },
106
+ getApi(apiId) {
107
+ return req("GET", `/v1/apis/${apiId}`);
108
+ },
109
+ updateApi(apiId, input) {
110
+ return req("PATCH", `/v1/apis/${apiId}`, input);
111
+ },
112
+ deleteApi(apiId) {
113
+ return req("DELETE", `/v1/apis/${apiId}`);
114
+ },
115
+ // ── Pricing ──────────────────────────────────────────────────────────
116
+ getPricing(apiId) {
117
+ return req("GET", `/v1/apis/${apiId}/pricing`);
118
+ },
119
+ setPricing(apiId, endpoints) {
120
+ return req("PUT", `/v1/apis/${apiId}/pricing`, { endpoints });
121
+ },
122
+ // ── Analytics ────────────────────────────────────────────────────────
123
+ getStats(apiId) {
124
+ return req("GET", `/v1/apis/${apiId}/stats`);
125
+ },
126
+ getPayments(apiId, options = {}) {
127
+ const params = new URLSearchParams();
128
+ if (options.limit) params.set("limit", String(options.limit));
129
+ if (options.from) params.set("from", options.from);
130
+ if (options.cursor) params.set("cursor", options.cursor);
131
+ const qs = params.toString() ? `?${params}` : "";
132
+ return req("GET", `/v1/apis/${apiId}/payments${qs}`);
133
+ },
134
+ getLogs(apiId, options = {}) {
135
+ const params = new URLSearchParams();
136
+ if (options.limit) params.set("limit", String(options.limit));
137
+ if (options.from) params.set("from", options.from);
138
+ if (options.cursor) params.set("cursor", options.cursor);
139
+ const qs = params.toString() ? `?${params}` : "";
140
+ return req("GET", `/v1/apis/${apiId}/logs${qs}`);
141
+ }
142
+ };
143
+ }
144
+ // Annotate the CommonJS export names for ESM import in node:
145
+ 0 && (module.exports = {
146
+ bootstrapAgentKeyEvm,
147
+ bootstrapAgentKeySolana,
148
+ createManagementClient
149
+ });
150
+ //# sourceMappingURL=management.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/management.ts"],"sourcesContent":["// src/management.ts\n// RelAI Management API client — create and manage monetised APIs programmatically.\n// Docs: https://relai.fi/documentation/management-api\n\nconst RELAI_API_BASE = 'https://api.relai.fi';\nconst BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ManagementClientConfig {\n /** Service key (sk_live_...) for authenticating management API calls */\n serviceKey: string;\n /** Override base URL (default: https://api.relai.fi) */\n baseUrl?: string;\n}\n\nexport interface RelaiApi {\n apiId: string;\n name: string;\n description?: string;\n baseUrl: string;\n subdomain?: string | null;\n network: string;\n facilitator: string;\n x402Version: number;\n status: string;\n merchantWallet: string;\n websiteUrl?: string;\n logoUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiEndpointInput {\n path: string;\n method: string;\n usdPrice: number;\n enabled?: boolean;\n}\n\nexport interface ApiEndpoint extends ApiEndpointInput {\n network: string;\n enabled: boolean;\n}\n\nexport interface CreateApiInput {\n name: string;\n baseUrl: string;\n merchantWallet: string;\n network: string;\n description?: string;\n websiteUrl?: string;\n logoUrl?: string;\n endpoints?: ApiEndpointInput[];\n}\n\nexport interface UpdateApiInput {\n name?: string;\n description?: string;\n baseUrl?: string;\n merchantWallet?: string;\n websiteUrl?: string;\n logoUrl?: string;\n}\n\nexport interface ApiStats {\n apiId: string;\n totalRequests: number;\n totalRevenue: number;\n currency: string;\n}\n\nexport interface ApiPayment {\n transaction: string;\n path: string;\n method: string;\n amount: number;\n currency: string;\n network: string;\n status: string;\n success: boolean;\n payer: string;\n createdAt: string;\n}\n\nexport interface ApiPaymentsResult {\n apiId: string;\n payments: ApiPayment[];\n nextCursor: string | null;\n}\n\nexport interface ApiLogItem {\n id: string;\n timestamp: string;\n method: string;\n path: string;\n status: string;\n cost: number;\n currency: string;\n duration: number;\n transaction: string;\n network: string;\n success: boolean;\n payer: string;\n}\n\nexport interface ApiLogsResult {\n items: ApiLogItem[];\n nextCursor: string | null;\n}\n\nexport interface AgentBootstrapResult {\n key: string;\n label: string;\n active: boolean;\n createdAt: string;\n}\n\n// ============================================================================\n// Agent bootstrap (autonomous key provisioning)\n// ============================================================================\n\n/**\n * Bootstrap a service key for a Solana agent.\n * Run once — store the returned key securely.\n *\n * @param keypair A Solana Keypair (from @solana/web3.js)\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeySolana(\n keypair: { publicKey: { toBase58(): string }; secretKey: Uint8Array },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const { sign } = await import('tweetnacl');\n\n const publicKey = keypair.publicKey.toBase58();\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2 — sign\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = sign.detached(msgBytes, keypair.secretKey);\n const signature = Buffer.from(sigBytes).toString('base64');\n\n // Step 3 — get service key\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n/**\n * Bootstrap a service key for an EVM agent.\n * Run once — store the returned key securely.\n *\n * @param wallet An ethers.js Wallet or Signer with address + signMessage\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeyEvm(\n wallet: { address: string; signMessage(message: string): Promise<string> },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const publicKey = wallet.address;\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2+3 — sign and get key\n const signature = await wallet.signMessage(message);\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n// ============================================================================\n// Management client\n// ============================================================================\n\nexport interface RelaiManagementClient {\n // APIs\n createApi(input: CreateApiInput): Promise<RelaiApi>;\n listApis(): Promise<RelaiApi[]>;\n getApi(apiId: string): Promise<RelaiApi>;\n updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;\n deleteApi(apiId: string): Promise<{ success: boolean; apiId: string }>;\n\n // Pricing\n getPricing(apiId: string): Promise<{ apiId: string; endpoints: ApiEndpoint[] }>;\n setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{ success: boolean; apiId: string; updated: number }>;\n\n // Analytics\n getStats(apiId: string): Promise<ApiStats>;\n getPayments(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiPaymentsResult>;\n getLogs(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiLogsResult>;\n}\n\n/**\n * Create a RelAI Management API client.\n *\n * @example\n * ```typescript\n * import { createManagementClient } from '@relai-fi/x402/management';\n *\n * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });\n *\n * const api = await mgmt.createApi({\n * name: 'My ML API',\n * baseUrl: 'https://inference.example.com',\n * merchantWallet: '0xYourWallet',\n * network: 'base',\n * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],\n * });\n * ```\n */\nexport function createManagementClient(config: ManagementClientConfig): RelaiManagementClient {\n const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\\/$/, '');\n const headers = {\n 'X-Service-Key': config.serviceKey,\n 'Content-Type': 'application/json',\n };\n\n async function req<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${base}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`[relai-mgmt] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n return {\n // ── APIs ──────────────────────────────────────────────────────────────\n\n createApi(input) {\n return req<RelaiApi>('POST', '/v1/apis', input);\n },\n\n async listApis() {\n const data = await req<{ apis: RelaiApi[] }>('GET', '/v1/apis');\n return data.apis;\n },\n\n getApi(apiId) {\n return req<RelaiApi>('GET', `/v1/apis/${apiId}`);\n },\n\n updateApi(apiId, input) {\n return req<RelaiApi>('PATCH', `/v1/apis/${apiId}`, input);\n },\n\n deleteApi(apiId) {\n return req<{ success: boolean; apiId: string }>('DELETE', `/v1/apis/${apiId}`);\n },\n\n // ── Pricing ──────────────────────────────────────────────────────────\n\n getPricing(apiId) {\n return req<{ apiId: string; endpoints: ApiEndpoint[] }>('GET', `/v1/apis/${apiId}/pricing`);\n },\n\n setPricing(apiId, endpoints) {\n return req<{ success: boolean; apiId: string; updated: number }>('PUT', `/v1/apis/${apiId}/pricing`, { endpoints });\n },\n\n // ── Analytics ────────────────────────────────────────────────────────\n\n getStats(apiId) {\n return req<ApiStats>('GET', `/v1/apis/${apiId}/stats`);\n },\n\n getPayments(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiPaymentsResult>('GET', `/v1/apis/${apiId}/payments${qs}`);\n },\n\n getLogs(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiLogsResult>('GET', `/v1/apis/${apiId}/logs${qs}`);\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,172 @@
1
+ interface ManagementClientConfig {
2
+ /** Service key (sk_live_...) for authenticating management API calls */
3
+ serviceKey: string;
4
+ /** Override base URL (default: https://api.relai.fi) */
5
+ baseUrl?: string;
6
+ }
7
+ interface RelaiApi {
8
+ apiId: string;
9
+ name: string;
10
+ description?: string;
11
+ baseUrl: string;
12
+ subdomain?: string | null;
13
+ network: string;
14
+ facilitator: string;
15
+ x402Version: number;
16
+ status: string;
17
+ merchantWallet: string;
18
+ websiteUrl?: string;
19
+ logoUrl?: string;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ }
23
+ interface ApiEndpointInput {
24
+ path: string;
25
+ method: string;
26
+ usdPrice: number;
27
+ enabled?: boolean;
28
+ }
29
+ interface ApiEndpoint extends ApiEndpointInput {
30
+ network: string;
31
+ enabled: boolean;
32
+ }
33
+ interface CreateApiInput {
34
+ name: string;
35
+ baseUrl: string;
36
+ merchantWallet: string;
37
+ network: string;
38
+ description?: string;
39
+ websiteUrl?: string;
40
+ logoUrl?: string;
41
+ endpoints?: ApiEndpointInput[];
42
+ }
43
+ interface UpdateApiInput {
44
+ name?: string;
45
+ description?: string;
46
+ baseUrl?: string;
47
+ merchantWallet?: string;
48
+ websiteUrl?: string;
49
+ logoUrl?: string;
50
+ }
51
+ interface ApiStats {
52
+ apiId: string;
53
+ totalRequests: number;
54
+ totalRevenue: number;
55
+ currency: string;
56
+ }
57
+ interface ApiPayment {
58
+ transaction: string;
59
+ path: string;
60
+ method: string;
61
+ amount: number;
62
+ currency: string;
63
+ network: string;
64
+ status: string;
65
+ success: boolean;
66
+ payer: string;
67
+ createdAt: string;
68
+ }
69
+ interface ApiPaymentsResult {
70
+ apiId: string;
71
+ payments: ApiPayment[];
72
+ nextCursor: string | null;
73
+ }
74
+ interface ApiLogItem {
75
+ id: string;
76
+ timestamp: string;
77
+ method: string;
78
+ path: string;
79
+ status: string;
80
+ cost: number;
81
+ currency: string;
82
+ duration: number;
83
+ transaction: string;
84
+ network: string;
85
+ success: boolean;
86
+ payer: string;
87
+ }
88
+ interface ApiLogsResult {
89
+ items: ApiLogItem[];
90
+ nextCursor: string | null;
91
+ }
92
+ interface AgentBootstrapResult {
93
+ key: string;
94
+ label: string;
95
+ active: boolean;
96
+ createdAt: string;
97
+ }
98
+ /**
99
+ * Bootstrap a service key for a Solana agent.
100
+ * Run once — store the returned key securely.
101
+ *
102
+ * @param keypair A Solana Keypair (from @solana/web3.js)
103
+ * @param label Human-readable label for the key
104
+ */
105
+ declare function bootstrapAgentKeySolana(keypair: {
106
+ publicKey: {
107
+ toBase58(): string;
108
+ };
109
+ secretKey: Uint8Array;
110
+ }, label?: string): Promise<AgentBootstrapResult>;
111
+ /**
112
+ * Bootstrap a service key for an EVM agent.
113
+ * Run once — store the returned key securely.
114
+ *
115
+ * @param wallet An ethers.js Wallet or Signer with address + signMessage
116
+ * @param label Human-readable label for the key
117
+ */
118
+ declare function bootstrapAgentKeyEvm(wallet: {
119
+ address: string;
120
+ signMessage(message: string): Promise<string>;
121
+ }, label?: string): Promise<AgentBootstrapResult>;
122
+ interface RelaiManagementClient {
123
+ createApi(input: CreateApiInput): Promise<RelaiApi>;
124
+ listApis(): Promise<RelaiApi[]>;
125
+ getApi(apiId: string): Promise<RelaiApi>;
126
+ updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;
127
+ deleteApi(apiId: string): Promise<{
128
+ success: boolean;
129
+ apiId: string;
130
+ }>;
131
+ getPricing(apiId: string): Promise<{
132
+ apiId: string;
133
+ endpoints: ApiEndpoint[];
134
+ }>;
135
+ setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{
136
+ success: boolean;
137
+ apiId: string;
138
+ updated: number;
139
+ }>;
140
+ getStats(apiId: string): Promise<ApiStats>;
141
+ getPayments(apiId: string, options?: {
142
+ limit?: number;
143
+ from?: string;
144
+ cursor?: string;
145
+ }): Promise<ApiPaymentsResult>;
146
+ getLogs(apiId: string, options?: {
147
+ limit?: number;
148
+ from?: string;
149
+ cursor?: string;
150
+ }): Promise<ApiLogsResult>;
151
+ }
152
+ /**
153
+ * Create a RelAI Management API client.
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * import { createManagementClient } from '@relai-fi/x402/management';
158
+ *
159
+ * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });
160
+ *
161
+ * const api = await mgmt.createApi({
162
+ * name: 'My ML API',
163
+ * baseUrl: 'https://inference.example.com',
164
+ * merchantWallet: '0xYourWallet',
165
+ * network: 'base',
166
+ * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],
167
+ * });
168
+ * ```
169
+ */
170
+ declare function createManagementClient(config: ManagementClientConfig): RelaiManagementClient;
171
+
172
+ export { type AgentBootstrapResult, type ApiEndpoint, type ApiEndpointInput, type ApiLogItem, type ApiLogsResult, type ApiPayment, type ApiPaymentsResult, type ApiStats, type CreateApiInput, type ManagementClientConfig, type RelaiApi, type RelaiManagementClient, type UpdateApiInput, bootstrapAgentKeyEvm, bootstrapAgentKeySolana, createManagementClient };
@@ -0,0 +1,172 @@
1
+ interface ManagementClientConfig {
2
+ /** Service key (sk_live_...) for authenticating management API calls */
3
+ serviceKey: string;
4
+ /** Override base URL (default: https://api.relai.fi) */
5
+ baseUrl?: string;
6
+ }
7
+ interface RelaiApi {
8
+ apiId: string;
9
+ name: string;
10
+ description?: string;
11
+ baseUrl: string;
12
+ subdomain?: string | null;
13
+ network: string;
14
+ facilitator: string;
15
+ x402Version: number;
16
+ status: string;
17
+ merchantWallet: string;
18
+ websiteUrl?: string;
19
+ logoUrl?: string;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ }
23
+ interface ApiEndpointInput {
24
+ path: string;
25
+ method: string;
26
+ usdPrice: number;
27
+ enabled?: boolean;
28
+ }
29
+ interface ApiEndpoint extends ApiEndpointInput {
30
+ network: string;
31
+ enabled: boolean;
32
+ }
33
+ interface CreateApiInput {
34
+ name: string;
35
+ baseUrl: string;
36
+ merchantWallet: string;
37
+ network: string;
38
+ description?: string;
39
+ websiteUrl?: string;
40
+ logoUrl?: string;
41
+ endpoints?: ApiEndpointInput[];
42
+ }
43
+ interface UpdateApiInput {
44
+ name?: string;
45
+ description?: string;
46
+ baseUrl?: string;
47
+ merchantWallet?: string;
48
+ websiteUrl?: string;
49
+ logoUrl?: string;
50
+ }
51
+ interface ApiStats {
52
+ apiId: string;
53
+ totalRequests: number;
54
+ totalRevenue: number;
55
+ currency: string;
56
+ }
57
+ interface ApiPayment {
58
+ transaction: string;
59
+ path: string;
60
+ method: string;
61
+ amount: number;
62
+ currency: string;
63
+ network: string;
64
+ status: string;
65
+ success: boolean;
66
+ payer: string;
67
+ createdAt: string;
68
+ }
69
+ interface ApiPaymentsResult {
70
+ apiId: string;
71
+ payments: ApiPayment[];
72
+ nextCursor: string | null;
73
+ }
74
+ interface ApiLogItem {
75
+ id: string;
76
+ timestamp: string;
77
+ method: string;
78
+ path: string;
79
+ status: string;
80
+ cost: number;
81
+ currency: string;
82
+ duration: number;
83
+ transaction: string;
84
+ network: string;
85
+ success: boolean;
86
+ payer: string;
87
+ }
88
+ interface ApiLogsResult {
89
+ items: ApiLogItem[];
90
+ nextCursor: string | null;
91
+ }
92
+ interface AgentBootstrapResult {
93
+ key: string;
94
+ label: string;
95
+ active: boolean;
96
+ createdAt: string;
97
+ }
98
+ /**
99
+ * Bootstrap a service key for a Solana agent.
100
+ * Run once — store the returned key securely.
101
+ *
102
+ * @param keypair A Solana Keypair (from @solana/web3.js)
103
+ * @param label Human-readable label for the key
104
+ */
105
+ declare function bootstrapAgentKeySolana(keypair: {
106
+ publicKey: {
107
+ toBase58(): string;
108
+ };
109
+ secretKey: Uint8Array;
110
+ }, label?: string): Promise<AgentBootstrapResult>;
111
+ /**
112
+ * Bootstrap a service key for an EVM agent.
113
+ * Run once — store the returned key securely.
114
+ *
115
+ * @param wallet An ethers.js Wallet or Signer with address + signMessage
116
+ * @param label Human-readable label for the key
117
+ */
118
+ declare function bootstrapAgentKeyEvm(wallet: {
119
+ address: string;
120
+ signMessage(message: string): Promise<string>;
121
+ }, label?: string): Promise<AgentBootstrapResult>;
122
+ interface RelaiManagementClient {
123
+ createApi(input: CreateApiInput): Promise<RelaiApi>;
124
+ listApis(): Promise<RelaiApi[]>;
125
+ getApi(apiId: string): Promise<RelaiApi>;
126
+ updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;
127
+ deleteApi(apiId: string): Promise<{
128
+ success: boolean;
129
+ apiId: string;
130
+ }>;
131
+ getPricing(apiId: string): Promise<{
132
+ apiId: string;
133
+ endpoints: ApiEndpoint[];
134
+ }>;
135
+ setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{
136
+ success: boolean;
137
+ apiId: string;
138
+ updated: number;
139
+ }>;
140
+ getStats(apiId: string): Promise<ApiStats>;
141
+ getPayments(apiId: string, options?: {
142
+ limit?: number;
143
+ from?: string;
144
+ cursor?: string;
145
+ }): Promise<ApiPaymentsResult>;
146
+ getLogs(apiId: string, options?: {
147
+ limit?: number;
148
+ from?: string;
149
+ cursor?: string;
150
+ }): Promise<ApiLogsResult>;
151
+ }
152
+ /**
153
+ * Create a RelAI Management API client.
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * import { createManagementClient } from '@relai-fi/x402/management';
158
+ *
159
+ * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });
160
+ *
161
+ * const api = await mgmt.createApi({
162
+ * name: 'My ML API',
163
+ * baseUrl: 'https://inference.example.com',
164
+ * merchantWallet: '0xYourWallet',
165
+ * network: 'base',
166
+ * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],
167
+ * });
168
+ * ```
169
+ */
170
+ declare function createManagementClient(config: ManagementClientConfig): RelaiManagementClient;
171
+
172
+ export { type AgentBootstrapResult, type ApiEndpoint, type ApiEndpointInput, type ApiLogItem, type ApiLogsResult, type ApiPayment, type ApiPaymentsResult, type ApiStats, type CreateApiInput, type ManagementClientConfig, type RelaiApi, type RelaiManagementClient, type UpdateApiInput, bootstrapAgentKeyEvm, bootstrapAgentKeySolana, createManagementClient };
@@ -0,0 +1,113 @@
1
+ // src/management.ts
2
+ var RELAI_API_BASE = "https://api.relai.fi";
3
+ var BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;
4
+ async function bootstrapAgentKeySolana(keypair, label = "agent") {
5
+ const { sign } = await import("tweetnacl");
6
+ const publicKey = keypair.publicKey.toBase58();
7
+ const challengeRes = await fetch(BOOTSTRAP_URL, {
8
+ method: "POST",
9
+ headers: { "Content-Type": "application/json" },
10
+ body: JSON.stringify({ publicKey })
11
+ });
12
+ if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);
13
+ const { message } = await challengeRes.json();
14
+ const msgBytes = new TextEncoder().encode(message);
15
+ const sigBytes = sign.detached(msgBytes, keypair.secretKey);
16
+ const signature = Buffer.from(sigBytes).toString("base64");
17
+ const keyRes = await fetch(BOOTSTRAP_URL, {
18
+ method: "POST",
19
+ headers: { "Content-Type": "application/json" },
20
+ body: JSON.stringify({ publicKey, signature, message, label })
21
+ });
22
+ if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);
23
+ return keyRes.json();
24
+ }
25
+ async function bootstrapAgentKeyEvm(wallet, label = "agent") {
26
+ const publicKey = wallet.address;
27
+ const challengeRes = await fetch(BOOTSTRAP_URL, {
28
+ method: "POST",
29
+ headers: { "Content-Type": "application/json" },
30
+ body: JSON.stringify({ publicKey })
31
+ });
32
+ if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);
33
+ const { message } = await challengeRes.json();
34
+ const signature = await wallet.signMessage(message);
35
+ const keyRes = await fetch(BOOTSTRAP_URL, {
36
+ method: "POST",
37
+ headers: { "Content-Type": "application/json" },
38
+ body: JSON.stringify({ publicKey, signature, message, label })
39
+ });
40
+ if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);
41
+ return keyRes.json();
42
+ }
43
+ function createManagementClient(config) {
44
+ const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\/$/, "");
45
+ const headers = {
46
+ "X-Service-Key": config.serviceKey,
47
+ "Content-Type": "application/json"
48
+ };
49
+ async function req(method, path, body) {
50
+ const res = await fetch(`${base}${path}`, {
51
+ method,
52
+ headers,
53
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {}
54
+ });
55
+ if (!res.ok) {
56
+ const text = await res.text().catch(() => "");
57
+ throw new Error(`[relai-mgmt] ${method} ${path} \u2192 ${res.status}: ${text}`);
58
+ }
59
+ return res.json();
60
+ }
61
+ return {
62
+ // ── APIs ──────────────────────────────────────────────────────────────
63
+ createApi(input) {
64
+ return req("POST", "/v1/apis", input);
65
+ },
66
+ async listApis() {
67
+ const data = await req("GET", "/v1/apis");
68
+ return data.apis;
69
+ },
70
+ getApi(apiId) {
71
+ return req("GET", `/v1/apis/${apiId}`);
72
+ },
73
+ updateApi(apiId, input) {
74
+ return req("PATCH", `/v1/apis/${apiId}`, input);
75
+ },
76
+ deleteApi(apiId) {
77
+ return req("DELETE", `/v1/apis/${apiId}`);
78
+ },
79
+ // ── Pricing ──────────────────────────────────────────────────────────
80
+ getPricing(apiId) {
81
+ return req("GET", `/v1/apis/${apiId}/pricing`);
82
+ },
83
+ setPricing(apiId, endpoints) {
84
+ return req("PUT", `/v1/apis/${apiId}/pricing`, { endpoints });
85
+ },
86
+ // ── Analytics ────────────────────────────────────────────────────────
87
+ getStats(apiId) {
88
+ return req("GET", `/v1/apis/${apiId}/stats`);
89
+ },
90
+ getPayments(apiId, options = {}) {
91
+ const params = new URLSearchParams();
92
+ if (options.limit) params.set("limit", String(options.limit));
93
+ if (options.from) params.set("from", options.from);
94
+ if (options.cursor) params.set("cursor", options.cursor);
95
+ const qs = params.toString() ? `?${params}` : "";
96
+ return req("GET", `/v1/apis/${apiId}/payments${qs}`);
97
+ },
98
+ getLogs(apiId, options = {}) {
99
+ const params = new URLSearchParams();
100
+ if (options.limit) params.set("limit", String(options.limit));
101
+ if (options.from) params.set("from", options.from);
102
+ if (options.cursor) params.set("cursor", options.cursor);
103
+ const qs = params.toString() ? `?${params}` : "";
104
+ return req("GET", `/v1/apis/${apiId}/logs${qs}`);
105
+ }
106
+ };
107
+ }
108
+ export {
109
+ bootstrapAgentKeyEvm,
110
+ bootstrapAgentKeySolana,
111
+ createManagementClient
112
+ };
113
+ //# sourceMappingURL=management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/management.ts"],"sourcesContent":["// src/management.ts\n// RelAI Management API client — create and manage monetised APIs programmatically.\n// Docs: https://relai.fi/documentation/management-api\n\nconst RELAI_API_BASE = 'https://api.relai.fi';\nconst BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ManagementClientConfig {\n /** Service key (sk_live_...) for authenticating management API calls */\n serviceKey: string;\n /** Override base URL (default: https://api.relai.fi) */\n baseUrl?: string;\n}\n\nexport interface RelaiApi {\n apiId: string;\n name: string;\n description?: string;\n baseUrl: string;\n subdomain?: string | null;\n network: string;\n facilitator: string;\n x402Version: number;\n status: string;\n merchantWallet: string;\n websiteUrl?: string;\n logoUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiEndpointInput {\n path: string;\n method: string;\n usdPrice: number;\n enabled?: boolean;\n}\n\nexport interface ApiEndpoint extends ApiEndpointInput {\n network: string;\n enabled: boolean;\n}\n\nexport interface CreateApiInput {\n name: string;\n baseUrl: string;\n merchantWallet: string;\n network: string;\n description?: string;\n websiteUrl?: string;\n logoUrl?: string;\n endpoints?: ApiEndpointInput[];\n}\n\nexport interface UpdateApiInput {\n name?: string;\n description?: string;\n baseUrl?: string;\n merchantWallet?: string;\n websiteUrl?: string;\n logoUrl?: string;\n}\n\nexport interface ApiStats {\n apiId: string;\n totalRequests: number;\n totalRevenue: number;\n currency: string;\n}\n\nexport interface ApiPayment {\n transaction: string;\n path: string;\n method: string;\n amount: number;\n currency: string;\n network: string;\n status: string;\n success: boolean;\n payer: string;\n createdAt: string;\n}\n\nexport interface ApiPaymentsResult {\n apiId: string;\n payments: ApiPayment[];\n nextCursor: string | null;\n}\n\nexport interface ApiLogItem {\n id: string;\n timestamp: string;\n method: string;\n path: string;\n status: string;\n cost: number;\n currency: string;\n duration: number;\n transaction: string;\n network: string;\n success: boolean;\n payer: string;\n}\n\nexport interface ApiLogsResult {\n items: ApiLogItem[];\n nextCursor: string | null;\n}\n\nexport interface AgentBootstrapResult {\n key: string;\n label: string;\n active: boolean;\n createdAt: string;\n}\n\n// ============================================================================\n// Agent bootstrap (autonomous key provisioning)\n// ============================================================================\n\n/**\n * Bootstrap a service key for a Solana agent.\n * Run once — store the returned key securely.\n *\n * @param keypair A Solana Keypair (from @solana/web3.js)\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeySolana(\n keypair: { publicKey: { toBase58(): string }; secretKey: Uint8Array },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const { sign } = await import('tweetnacl');\n\n const publicKey = keypair.publicKey.toBase58();\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2 — sign\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = sign.detached(msgBytes, keypair.secretKey);\n const signature = Buffer.from(sigBytes).toString('base64');\n\n // Step 3 — get service key\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n/**\n * Bootstrap a service key for an EVM agent.\n * Run once — store the returned key securely.\n *\n * @param wallet An ethers.js Wallet or Signer with address + signMessage\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeyEvm(\n wallet: { address: string; signMessage(message: string): Promise<string> },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const publicKey = wallet.address;\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2+3 — sign and get key\n const signature = await wallet.signMessage(message);\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n// ============================================================================\n// Management client\n// ============================================================================\n\nexport interface RelaiManagementClient {\n // APIs\n createApi(input: CreateApiInput): Promise<RelaiApi>;\n listApis(): Promise<RelaiApi[]>;\n getApi(apiId: string): Promise<RelaiApi>;\n updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;\n deleteApi(apiId: string): Promise<{ success: boolean; apiId: string }>;\n\n // Pricing\n getPricing(apiId: string): Promise<{ apiId: string; endpoints: ApiEndpoint[] }>;\n setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{ success: boolean; apiId: string; updated: number }>;\n\n // Analytics\n getStats(apiId: string): Promise<ApiStats>;\n getPayments(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiPaymentsResult>;\n getLogs(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiLogsResult>;\n}\n\n/**\n * Create a RelAI Management API client.\n *\n * @example\n * ```typescript\n * import { createManagementClient } from '@relai-fi/x402/management';\n *\n * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });\n *\n * const api = await mgmt.createApi({\n * name: 'My ML API',\n * baseUrl: 'https://inference.example.com',\n * merchantWallet: '0xYourWallet',\n * network: 'base',\n * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],\n * });\n * ```\n */\nexport function createManagementClient(config: ManagementClientConfig): RelaiManagementClient {\n const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\\/$/, '');\n const headers = {\n 'X-Service-Key': config.serviceKey,\n 'Content-Type': 'application/json',\n };\n\n async function req<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${base}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`[relai-mgmt] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n return {\n // ── APIs ──────────────────────────────────────────────────────────────\n\n createApi(input) {\n return req<RelaiApi>('POST', '/v1/apis', input);\n },\n\n async listApis() {\n const data = await req<{ apis: RelaiApi[] }>('GET', '/v1/apis');\n return data.apis;\n },\n\n getApi(apiId) {\n return req<RelaiApi>('GET', `/v1/apis/${apiId}`);\n },\n\n updateApi(apiId, input) {\n return req<RelaiApi>('PATCH', `/v1/apis/${apiId}`, input);\n },\n\n deleteApi(apiId) {\n return req<{ success: boolean; apiId: string }>('DELETE', `/v1/apis/${apiId}`);\n },\n\n // ── Pricing ──────────────────────────────────────────────────────────\n\n getPricing(apiId) {\n return req<{ apiId: string; endpoints: ApiEndpoint[] }>('GET', `/v1/apis/${apiId}/pricing`);\n },\n\n setPricing(apiId, endpoints) {\n return req<{ success: boolean; apiId: string; updated: number }>('PUT', `/v1/apis/${apiId}/pricing`, { endpoints });\n },\n\n // ── Analytics ────────────────────────────────────────────────────────\n\n getStats(apiId) {\n return req<ApiStats>('GET', `/v1/apis/${apiId}/stats`);\n },\n\n getPayments(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiPaymentsResult>('GET', `/v1/apis/${apiId}/payments${qs}`);\n },\n\n getLogs(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiLogsResult>('GET', `/v1/apis/${apiId}/logs${qs}`);\n },\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relai-fi/x402",
3
- "version": "0.5.24",
3
+ "version": "0.5.26",
4
4
  "description": "Unified x402 payment SDK for Solana, Base, Avalanche, SKALE Base, SKALE BITE, Polygon, and Ethereum. Automatic 402 handling with zero gas fees.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -85,6 +85,11 @@
85
85
  "types": "./dist/utils/index.d.ts",
86
86
  "import": "./dist/utils/index.js",
87
87
  "require": "./dist/utils/index.cjs"
88
+ },
89
+ "./management": {
90
+ "types": "./dist/management.d.ts",
91
+ "import": "./dist/management.js",
92
+ "require": "./dist/management.cjs"
88
93
  }
89
94
  }
90
95
  }