@moneymq/sdk 0.3.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +718 -60
- package/dist/index.d.ts +718 -60
- package/dist/index.js +492 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +482 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -2
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
// src/catalog.ts
|
|
2
|
+
var PaymentRequiredError = class extends Error {
|
|
3
|
+
constructor(message, paymentRequirements, raw) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.paymentRequirements = paymentRequirements;
|
|
6
|
+
this.raw = raw;
|
|
7
|
+
this.name = "PaymentRequiredError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
2
10
|
var ProductsAPI = class {
|
|
3
11
|
constructor(config) {
|
|
4
12
|
this.config = config;
|
|
@@ -39,7 +47,15 @@ var ProductsAPI = class {
|
|
|
39
47
|
if (params?.limit) query.set("limit", String(params.limit));
|
|
40
48
|
if (params?.startingAfter) query.set("starting_after", params.startingAfter);
|
|
41
49
|
const queryString = query.toString();
|
|
42
|
-
|
|
50
|
+
const result = await this.request(
|
|
51
|
+
"GET",
|
|
52
|
+
`/catalog/v1/products${queryString ? `?${queryString}` : ""}`
|
|
53
|
+
);
|
|
54
|
+
result.data = result.data.map((product) => ({
|
|
55
|
+
...product,
|
|
56
|
+
accessUrl: `${this.config.endpoint}/catalog/v1/products/${product.id}/access`
|
|
57
|
+
}));
|
|
58
|
+
return result;
|
|
43
59
|
}
|
|
44
60
|
/**
|
|
45
61
|
* Update a product
|
|
@@ -53,6 +69,59 @@ var ProductsAPI = class {
|
|
|
53
69
|
async delete(id) {
|
|
54
70
|
return this.request("DELETE", `/catalog/v1/products/${id}`);
|
|
55
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Access a product - gated by x402 payment
|
|
74
|
+
*
|
|
75
|
+
* This endpoint requires payment. If no payment header is provided (or payment is invalid),
|
|
76
|
+
* throws a PaymentRequiredError with the payment requirements.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* try {
|
|
81
|
+
* // First attempt without payment - will throw PaymentRequiredError
|
|
82
|
+
* const access = await moneymq.catalog.products.access('surfnet-max');
|
|
83
|
+
* } catch (error) {
|
|
84
|
+
* if (error instanceof PaymentRequiredError) {
|
|
85
|
+
* // Get payment requirements and create payment
|
|
86
|
+
* const requirements = error.paymentRequirements[0];
|
|
87
|
+
* const paymentHeader = await createPayment(requirements);
|
|
88
|
+
*
|
|
89
|
+
* // Retry with payment
|
|
90
|
+
* const access = await moneymq.catalog.products.access('surfnet-max', {
|
|
91
|
+
* paymentHeader,
|
|
92
|
+
* });
|
|
93
|
+
* }
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
async access(id, params) {
|
|
98
|
+
const url = `${this.config.endpoint}/catalog/v1/products/${id}/access`;
|
|
99
|
+
const headers = { "Content-Type": "application/json" };
|
|
100
|
+
if (this.config.secret) {
|
|
101
|
+
headers["Authorization"] = `Bearer ${this.config.secret}`;
|
|
102
|
+
}
|
|
103
|
+
if (params?.paymentHeader) {
|
|
104
|
+
headers["X-Payment"] = params.paymentHeader;
|
|
105
|
+
}
|
|
106
|
+
const response = await fetch(url, {
|
|
107
|
+
method: "GET",
|
|
108
|
+
headers
|
|
109
|
+
});
|
|
110
|
+
if (response.status === 402) {
|
|
111
|
+
const x402Response = await response.json().catch(() => ({}));
|
|
112
|
+
const paymentRequirements = x402Response.accepts || [];
|
|
113
|
+
throw new PaymentRequiredError(
|
|
114
|
+
"Payment required",
|
|
115
|
+
paymentRequirements,
|
|
116
|
+
x402Response
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
const errorData = await response.json().catch(() => ({}));
|
|
121
|
+
throw new Error(errorData.message || `Request failed: ${response.status}`);
|
|
122
|
+
}
|
|
123
|
+
return response.json();
|
|
124
|
+
}
|
|
56
125
|
};
|
|
57
126
|
var PricesAPI = class {
|
|
58
127
|
constructor(config) {
|
|
@@ -256,15 +325,92 @@ var WebhooksAPI = class {
|
|
|
256
325
|
return this.request("POST", "/payment/v1/webhooks/test", { event, data });
|
|
257
326
|
}
|
|
258
327
|
};
|
|
328
|
+
var PaymentIntentsAPI = class {
|
|
329
|
+
constructor(config) {
|
|
330
|
+
this.request = createRequester(config);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Create a payment intent
|
|
334
|
+
* Use this for simple payments without the full checkout session flow
|
|
335
|
+
*/
|
|
336
|
+
async create(params) {
|
|
337
|
+
return this.request("POST", "/catalog/v1/payment_intents", params);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Retrieve a payment intent
|
|
341
|
+
*/
|
|
342
|
+
async retrieve(id) {
|
|
343
|
+
return this.request("GET", `/catalog/v1/payment_intents/${id}`);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Confirm a payment intent
|
|
347
|
+
* This triggers the actual payment (and x402 flow if required)
|
|
348
|
+
*/
|
|
349
|
+
async confirm(id) {
|
|
350
|
+
return this.request("POST", `/catalog/v1/payment_intents/${id}/confirm`, {});
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Cancel a payment intent
|
|
354
|
+
*/
|
|
355
|
+
async cancel(id) {
|
|
356
|
+
return this.request("POST", `/catalog/v1/payment_intents/${id}/cancel`, {});
|
|
357
|
+
}
|
|
358
|
+
};
|
|
259
359
|
var PaymentAPI = class {
|
|
260
360
|
constructor(config) {
|
|
261
361
|
this.request = createRequester(config);
|
|
262
362
|
this.checkout = new CheckoutAPI(config);
|
|
363
|
+
this.intents = new PaymentIntentsAPI(config);
|
|
263
364
|
this.links = new LinksAPI(config);
|
|
264
365
|
this.customers = new CustomersAPI(config);
|
|
265
366
|
this.payouts = new PayoutsAPI(config);
|
|
266
367
|
this.webhooks = new WebhooksAPI(config);
|
|
267
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* Simple one-liner payment - creates a checkout session with inline product data
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```ts
|
|
374
|
+
* const result = await moneymq.payment.pay({
|
|
375
|
+
* amount: 999,
|
|
376
|
+
* currency: 'usd',
|
|
377
|
+
* productName: 'Pro Plan',
|
|
378
|
+
* productId: 'pro-plan',
|
|
379
|
+
* customer: 'wallet_address',
|
|
380
|
+
* });
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
async pay(params) {
|
|
384
|
+
const session = await this.request("POST", "/catalog/v1/checkout/sessions", {
|
|
385
|
+
line_items: [
|
|
386
|
+
{
|
|
387
|
+
price_data: {
|
|
388
|
+
currency: params.currency,
|
|
389
|
+
unit_amount: params.amount,
|
|
390
|
+
product_data: {
|
|
391
|
+
name: params.productName,
|
|
392
|
+
description: params.description,
|
|
393
|
+
metadata: {
|
|
394
|
+
product_id: params.productId || params.productName.toLowerCase().replace(/\s+/g, "-")
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
quantity: 1
|
|
399
|
+
}
|
|
400
|
+
],
|
|
401
|
+
customer: params.customer,
|
|
402
|
+
metadata: params.metadata,
|
|
403
|
+
mode: "payment"
|
|
404
|
+
});
|
|
405
|
+
return {
|
|
406
|
+
sessionId: session.id,
|
|
407
|
+
paymentIntentId: session.payment_intent,
|
|
408
|
+
clientSecret: session.client_secret,
|
|
409
|
+
amount: session.amount_total,
|
|
410
|
+
currency: session.currency,
|
|
411
|
+
status: "requires_confirmation"
|
|
412
|
+
};
|
|
413
|
+
}
|
|
268
414
|
/**
|
|
269
415
|
* Retrieve a payment by ID
|
|
270
416
|
*/
|
|
@@ -285,8 +431,329 @@ var PaymentAPI = class {
|
|
|
285
431
|
}
|
|
286
432
|
};
|
|
287
433
|
|
|
434
|
+
// src/config.ts
|
|
435
|
+
async function fetchConfig(apiUrl) {
|
|
436
|
+
const response = await fetch(`${apiUrl}/config`);
|
|
437
|
+
if (!response.ok) {
|
|
438
|
+
throw new Error(`Failed to fetch config: ${response.status}`);
|
|
439
|
+
}
|
|
440
|
+
return response.json();
|
|
441
|
+
}
|
|
442
|
+
async function getRpcUrl(apiUrl, fallback = "https://api.devnet.solana.com") {
|
|
443
|
+
try {
|
|
444
|
+
const config = await fetchConfig(apiUrl);
|
|
445
|
+
return config.x402.validator.rpcUrl || fallback;
|
|
446
|
+
} catch {
|
|
447
|
+
return fallback;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// src/x402.ts
|
|
452
|
+
import { createSigner } from "x402-fetch";
|
|
453
|
+
var X402API = class {
|
|
454
|
+
constructor(config) {
|
|
455
|
+
this.config = config;
|
|
456
|
+
this.serverConfig = null;
|
|
457
|
+
this.sandboxAccounts = null;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Fetch sandbox accounts from the server
|
|
461
|
+
*/
|
|
462
|
+
async fetchSandboxAccounts() {
|
|
463
|
+
if (this.sandboxAccounts) {
|
|
464
|
+
return this.sandboxAccounts;
|
|
465
|
+
}
|
|
466
|
+
const response = await fetch(`${this.config.endpoint}/sandbox/accounts`);
|
|
467
|
+
if (!response.ok) {
|
|
468
|
+
throw new Error(`Failed to fetch sandbox accounts: ${response.status}`);
|
|
469
|
+
}
|
|
470
|
+
this.sandboxAccounts = await response.json();
|
|
471
|
+
return this.sandboxAccounts;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get a signer for a sandbox account by tag/label
|
|
475
|
+
*
|
|
476
|
+
* @param params - Parameters containing the wallet tag/label
|
|
477
|
+
* @returns A Signer that can be used directly with wrapFetchWithPayment
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* ```typescript
|
|
481
|
+
* const payer = await moneymq.x402.getSigner({ tag: 'alice' });
|
|
482
|
+
* ```
|
|
483
|
+
*/
|
|
484
|
+
async getSigner(params) {
|
|
485
|
+
const accounts = await this.fetchSandboxAccounts();
|
|
486
|
+
for (const networkData of Object.values(accounts)) {
|
|
487
|
+
for (const account of networkData.userAccounts) {
|
|
488
|
+
if (account.label === params.tag) {
|
|
489
|
+
if (!account.secretKeyHex) {
|
|
490
|
+
throw new Error(`Account '${params.tag}' does not have a secret key (not locally managed)`);
|
|
491
|
+
}
|
|
492
|
+
return createSigner("solana", account.secretKeyHex);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
throw new Error(`No sandbox account found with label '${params.tag}'`);
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Get x402 configuration for use with wrapFetchWithPayment
|
|
500
|
+
*
|
|
501
|
+
* @returns Configuration object compatible with x402-fetch
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```typescript
|
|
505
|
+
* const config = await moneymq.x402.getConfig();
|
|
506
|
+
* const fetchWithPayment = wrapFetchWithPayment(fetch, payer, undefined, undefined, config);
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
async getConfig() {
|
|
510
|
+
if (!this.serverConfig) {
|
|
511
|
+
this.serverConfig = await fetchConfig(this.config.endpoint);
|
|
512
|
+
}
|
|
513
|
+
return {
|
|
514
|
+
svmConfig: {
|
|
515
|
+
rpcUrl: this.serverConfig.x402.validator.rpcUrl
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Get the full server configuration
|
|
521
|
+
*
|
|
522
|
+
* @returns The complete server configuration including x402 settings
|
|
523
|
+
*/
|
|
524
|
+
async getServerConfig() {
|
|
525
|
+
if (!this.serverConfig) {
|
|
526
|
+
this.serverConfig = await fetchConfig(this.config.endpoint);
|
|
527
|
+
}
|
|
528
|
+
return this.serverConfig;
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
// src/events.ts
|
|
533
|
+
var EventStream = class {
|
|
534
|
+
constructor(endpoint, options = {}) {
|
|
535
|
+
this.eventSource = null;
|
|
536
|
+
this.state = "disconnected";
|
|
537
|
+
this.reconnectAttempts = 0;
|
|
538
|
+
this.lastEventId = null;
|
|
539
|
+
this.paymentHandlers = /* @__PURE__ */ new Set();
|
|
540
|
+
this.errorHandlers = /* @__PURE__ */ new Set();
|
|
541
|
+
this.stateHandlers = /* @__PURE__ */ new Set();
|
|
542
|
+
this.endpoint = endpoint;
|
|
543
|
+
console.log("[MoneyMQ SDK] EventStream constructor called with options:", JSON.stringify(options));
|
|
544
|
+
this.options = {
|
|
545
|
+
last: options.last ?? 0,
|
|
546
|
+
cursor: options.cursor ?? "",
|
|
547
|
+
streamId: options.streamId ?? "",
|
|
548
|
+
autoReconnect: options.autoReconnect ?? true,
|
|
549
|
+
reconnectDelay: options.reconnectDelay ?? 1e3,
|
|
550
|
+
maxReconnectAttempts: options.maxReconnectAttempts ?? 0
|
|
551
|
+
};
|
|
552
|
+
console.log("[MoneyMQ SDK] Resolved options:", JSON.stringify(this.options));
|
|
553
|
+
if (this.options.cursor && !this.options.streamId) {
|
|
554
|
+
this.lastEventId = this.options.cursor;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Whether this is a stateful stream (server tracks cursor)
|
|
559
|
+
*/
|
|
560
|
+
get isStateful() {
|
|
561
|
+
return this.options.streamId !== "";
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* The stream ID for stateful streams
|
|
565
|
+
*/
|
|
566
|
+
get streamId() {
|
|
567
|
+
return this.options.streamId || null;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Current connection state
|
|
571
|
+
*/
|
|
572
|
+
get connectionState() {
|
|
573
|
+
return this.state;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Current cursor (last received event ID)
|
|
577
|
+
*/
|
|
578
|
+
get cursor() {
|
|
579
|
+
return this.lastEventId;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Whether the stream is currently connected
|
|
583
|
+
*/
|
|
584
|
+
get isConnected() {
|
|
585
|
+
return this.state === "connected";
|
|
586
|
+
}
|
|
587
|
+
on(event, handler) {
|
|
588
|
+
switch (event) {
|
|
589
|
+
case "payment":
|
|
590
|
+
this.paymentHandlers.add(handler);
|
|
591
|
+
return () => this.paymentHandlers.delete(handler);
|
|
592
|
+
case "error":
|
|
593
|
+
this.errorHandlers.add(handler);
|
|
594
|
+
return () => this.errorHandlers.delete(handler);
|
|
595
|
+
case "stateChange":
|
|
596
|
+
this.stateHandlers.add(handler);
|
|
597
|
+
return () => this.stateHandlers.delete(handler);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
off(event, handler) {
|
|
601
|
+
switch (event) {
|
|
602
|
+
case "payment":
|
|
603
|
+
this.paymentHandlers.delete(handler);
|
|
604
|
+
break;
|
|
605
|
+
case "error":
|
|
606
|
+
this.errorHandlers.delete(handler);
|
|
607
|
+
break;
|
|
608
|
+
case "stateChange":
|
|
609
|
+
this.stateHandlers.delete(handler);
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Connect to the event stream
|
|
615
|
+
*/
|
|
616
|
+
connect() {
|
|
617
|
+
if (this.eventSource) {
|
|
618
|
+
this.eventSource.close();
|
|
619
|
+
}
|
|
620
|
+
this.setState("connecting");
|
|
621
|
+
const url = this.buildUrl();
|
|
622
|
+
console.log("[MoneyMQ SDK] Connecting to SSE:", url, "| streamId:", this.options.streamId || "(none)");
|
|
623
|
+
this.eventSource = new EventSource(url);
|
|
624
|
+
this.eventSource.onopen = () => {
|
|
625
|
+
this.setState("connected");
|
|
626
|
+
this.reconnectAttempts = 0;
|
|
627
|
+
};
|
|
628
|
+
this.eventSource.addEventListener("payment", (event) => {
|
|
629
|
+
try {
|
|
630
|
+
const cloudEvent = JSON.parse(event.data);
|
|
631
|
+
this.lastEventId = cloudEvent.id;
|
|
632
|
+
this.emitPayment(cloudEvent);
|
|
633
|
+
} catch (e) {
|
|
634
|
+
this.emitError(new Error(`Failed to parse event: ${e}`));
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
this.eventSource.onerror = () => {
|
|
638
|
+
this.eventSource?.close();
|
|
639
|
+
this.eventSource = null;
|
|
640
|
+
if (this.options.autoReconnect && this.shouldReconnect()) {
|
|
641
|
+
this.scheduleReconnect();
|
|
642
|
+
} else {
|
|
643
|
+
this.setState("disconnected");
|
|
644
|
+
this.emitError(new Error("Connection lost"));
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Disconnect from the event stream
|
|
650
|
+
*/
|
|
651
|
+
disconnect() {
|
|
652
|
+
if (this.eventSource) {
|
|
653
|
+
this.eventSource.close();
|
|
654
|
+
this.eventSource = null;
|
|
655
|
+
}
|
|
656
|
+
this.setState("disconnected");
|
|
657
|
+
this.reconnectAttempts = 0;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Reconnect with a new cursor
|
|
661
|
+
* Useful for resuming from a stored position
|
|
662
|
+
*/
|
|
663
|
+
reconnectFrom(cursor) {
|
|
664
|
+
this.lastEventId = cursor;
|
|
665
|
+
this.disconnect();
|
|
666
|
+
this.connect();
|
|
667
|
+
}
|
|
668
|
+
buildUrl() {
|
|
669
|
+
const params = new URLSearchParams();
|
|
670
|
+
if (this.options.streamId) {
|
|
671
|
+
params.set("stream_id", this.options.streamId);
|
|
672
|
+
if (this.options.last > 0) {
|
|
673
|
+
params.set("last", this.options.last.toString());
|
|
674
|
+
}
|
|
675
|
+
} else {
|
|
676
|
+
if (this.lastEventId) {
|
|
677
|
+
params.set("cursor", this.lastEventId);
|
|
678
|
+
} else if (this.options.last > 0) {
|
|
679
|
+
params.set("last", this.options.last.toString());
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
const queryString = params.toString();
|
|
683
|
+
return queryString ? `${this.endpoint}/events?${queryString}` : `${this.endpoint}/events`;
|
|
684
|
+
}
|
|
685
|
+
setState(state) {
|
|
686
|
+
if (this.state !== state) {
|
|
687
|
+
this.state = state;
|
|
688
|
+
this.stateHandlers.forEach((handler) => handler(state));
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
shouldReconnect() {
|
|
692
|
+
if (this.options.maxReconnectAttempts === 0) return true;
|
|
693
|
+
return this.reconnectAttempts < this.options.maxReconnectAttempts;
|
|
694
|
+
}
|
|
695
|
+
scheduleReconnect() {
|
|
696
|
+
this.setState("reconnecting");
|
|
697
|
+
this.reconnectAttempts++;
|
|
698
|
+
setTimeout(() => {
|
|
699
|
+
if (this.state === "reconnecting") {
|
|
700
|
+
this.connect();
|
|
701
|
+
}
|
|
702
|
+
}, this.options.reconnectDelay);
|
|
703
|
+
}
|
|
704
|
+
emitPayment(event) {
|
|
705
|
+
this.paymentHandlers.forEach((handler) => handler(event));
|
|
706
|
+
}
|
|
707
|
+
emitError(error) {
|
|
708
|
+
this.errorHandlers.forEach((handler) => handler(error));
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
function createEventStream(endpoint, options) {
|
|
712
|
+
return new EventStream(endpoint, options);
|
|
713
|
+
}
|
|
714
|
+
function isPaymentVerificationSucceeded(event) {
|
|
715
|
+
return event.type === "mq.money.payment.verification.succeeded";
|
|
716
|
+
}
|
|
717
|
+
function isPaymentVerificationFailed(event) {
|
|
718
|
+
return event.type === "mq.money.payment.verification.failed";
|
|
719
|
+
}
|
|
720
|
+
function isPaymentSettlementSucceeded(event) {
|
|
721
|
+
return event.type === "mq.money.payment.settlement.succeeded";
|
|
722
|
+
}
|
|
723
|
+
function isPaymentSettlementFailed(event) {
|
|
724
|
+
return event.type === "mq.money.payment.settlement.failed";
|
|
725
|
+
}
|
|
726
|
+
function parseCloudEvent(data) {
|
|
727
|
+
try {
|
|
728
|
+
return JSON.parse(data);
|
|
729
|
+
} catch {
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
function buildEventStreamUrl(endpoint, options) {
|
|
734
|
+
const params = new URLSearchParams();
|
|
735
|
+
if (options?.streamId) {
|
|
736
|
+
params.set("stream_id", options.streamId);
|
|
737
|
+
if (options.last && options.last > 0) {
|
|
738
|
+
params.set("last", options.last.toString());
|
|
739
|
+
}
|
|
740
|
+
} else {
|
|
741
|
+
if (options?.cursor) {
|
|
742
|
+
params.set("cursor", options.cursor);
|
|
743
|
+
} else if (options?.last && options.last > 0) {
|
|
744
|
+
params.set("last", options.last.toString());
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
const queryString = params.toString();
|
|
748
|
+
return queryString ? `${endpoint}/events?${queryString}` : `${endpoint}/events`;
|
|
749
|
+
}
|
|
750
|
+
|
|
288
751
|
// src/client.ts
|
|
289
752
|
var MoneyMQ = class {
|
|
753
|
+
/** MoneyMQ API endpoint */
|
|
754
|
+
get endpoint() {
|
|
755
|
+
return this.config.endpoint;
|
|
756
|
+
}
|
|
290
757
|
constructor(config) {
|
|
291
758
|
this.config = {
|
|
292
759
|
timeout: 3e4,
|
|
@@ -294,6 +761,10 @@ var MoneyMQ = class {
|
|
|
294
761
|
};
|
|
295
762
|
this.catalog = new CatalogAPI(this.config);
|
|
296
763
|
this.payment = new PaymentAPI(this.config);
|
|
764
|
+
this.x402 = new X402API(this.config);
|
|
765
|
+
this.events = {
|
|
766
|
+
stream: (options) => new EventStream(this.config.endpoint, options)
|
|
767
|
+
};
|
|
297
768
|
}
|
|
298
769
|
/**
|
|
299
770
|
* Make an authenticated request to the MoneyMQ API
|
|
@@ -331,26 +802,18 @@ var MoneyMQError = class extends Error {
|
|
|
331
802
|
this.name = "MoneyMQError";
|
|
332
803
|
}
|
|
333
804
|
};
|
|
334
|
-
|
|
335
|
-
// src/config.ts
|
|
336
|
-
async function fetchConfig(apiUrl) {
|
|
337
|
-
const response = await fetch(`${apiUrl}/config`);
|
|
338
|
-
if (!response.ok) {
|
|
339
|
-
throw new Error(`Failed to fetch config: ${response.status}`);
|
|
340
|
-
}
|
|
341
|
-
return response.json();
|
|
342
|
-
}
|
|
343
|
-
async function getRpcUrl(apiUrl, fallback = "https://api.devnet.solana.com") {
|
|
344
|
-
try {
|
|
345
|
-
const config = await fetchConfig(apiUrl);
|
|
346
|
-
return config.x402.validator.rpcUrl || fallback;
|
|
347
|
-
} catch {
|
|
348
|
-
return fallback;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
805
|
export {
|
|
806
|
+
EventStream,
|
|
352
807
|
MoneyMQ,
|
|
808
|
+
PaymentRequiredError,
|
|
809
|
+
buildEventStreamUrl,
|
|
810
|
+
createEventStream,
|
|
353
811
|
fetchConfig,
|
|
354
|
-
getRpcUrl
|
|
812
|
+
getRpcUrl,
|
|
813
|
+
isPaymentSettlementFailed,
|
|
814
|
+
isPaymentSettlementSucceeded,
|
|
815
|
+
isPaymentVerificationFailed,
|
|
816
|
+
isPaymentVerificationSucceeded,
|
|
817
|
+
parseCloudEvent
|
|
355
818
|
};
|
|
356
819
|
//# sourceMappingURL=index.mjs.map
|