@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.js
CHANGED
|
@@ -20,13 +20,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
EventStream: () => EventStream,
|
|
23
24
|
MoneyMQ: () => MoneyMQ,
|
|
25
|
+
PaymentRequiredError: () => PaymentRequiredError,
|
|
26
|
+
buildEventStreamUrl: () => buildEventStreamUrl,
|
|
27
|
+
createEventStream: () => createEventStream,
|
|
24
28
|
fetchConfig: () => fetchConfig,
|
|
25
|
-
getRpcUrl: () => getRpcUrl
|
|
29
|
+
getRpcUrl: () => getRpcUrl,
|
|
30
|
+
isPaymentSettlementFailed: () => isPaymentSettlementFailed,
|
|
31
|
+
isPaymentSettlementSucceeded: () => isPaymentSettlementSucceeded,
|
|
32
|
+
isPaymentVerificationFailed: () => isPaymentVerificationFailed,
|
|
33
|
+
isPaymentVerificationSucceeded: () => isPaymentVerificationSucceeded,
|
|
34
|
+
parseCloudEvent: () => parseCloudEvent
|
|
26
35
|
});
|
|
27
36
|
module.exports = __toCommonJS(index_exports);
|
|
28
37
|
|
|
29
38
|
// src/catalog.ts
|
|
39
|
+
var PaymentRequiredError = class extends Error {
|
|
40
|
+
constructor(message, paymentRequirements, raw) {
|
|
41
|
+
super(message);
|
|
42
|
+
this.paymentRequirements = paymentRequirements;
|
|
43
|
+
this.raw = raw;
|
|
44
|
+
this.name = "PaymentRequiredError";
|
|
45
|
+
}
|
|
46
|
+
};
|
|
30
47
|
var ProductsAPI = class {
|
|
31
48
|
constructor(config) {
|
|
32
49
|
this.config = config;
|
|
@@ -67,7 +84,15 @@ var ProductsAPI = class {
|
|
|
67
84
|
if (params?.limit) query.set("limit", String(params.limit));
|
|
68
85
|
if (params?.startingAfter) query.set("starting_after", params.startingAfter);
|
|
69
86
|
const queryString = query.toString();
|
|
70
|
-
|
|
87
|
+
const result = await this.request(
|
|
88
|
+
"GET",
|
|
89
|
+
`/catalog/v1/products${queryString ? `?${queryString}` : ""}`
|
|
90
|
+
);
|
|
91
|
+
result.data = result.data.map((product) => ({
|
|
92
|
+
...product,
|
|
93
|
+
accessUrl: `${this.config.endpoint}/catalog/v1/products/${product.id}/access`
|
|
94
|
+
}));
|
|
95
|
+
return result;
|
|
71
96
|
}
|
|
72
97
|
/**
|
|
73
98
|
* Update a product
|
|
@@ -81,6 +106,59 @@ var ProductsAPI = class {
|
|
|
81
106
|
async delete(id) {
|
|
82
107
|
return this.request("DELETE", `/catalog/v1/products/${id}`);
|
|
83
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Access a product - gated by x402 payment
|
|
111
|
+
*
|
|
112
|
+
* This endpoint requires payment. If no payment header is provided (or payment is invalid),
|
|
113
|
+
* throws a PaymentRequiredError with the payment requirements.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* try {
|
|
118
|
+
* // First attempt without payment - will throw PaymentRequiredError
|
|
119
|
+
* const access = await moneymq.catalog.products.access('surfnet-max');
|
|
120
|
+
* } catch (error) {
|
|
121
|
+
* if (error instanceof PaymentRequiredError) {
|
|
122
|
+
* // Get payment requirements and create payment
|
|
123
|
+
* const requirements = error.paymentRequirements[0];
|
|
124
|
+
* const paymentHeader = await createPayment(requirements);
|
|
125
|
+
*
|
|
126
|
+
* // Retry with payment
|
|
127
|
+
* const access = await moneymq.catalog.products.access('surfnet-max', {
|
|
128
|
+
* paymentHeader,
|
|
129
|
+
* });
|
|
130
|
+
* }
|
|
131
|
+
* }
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
async access(id, params) {
|
|
135
|
+
const url = `${this.config.endpoint}/catalog/v1/products/${id}/access`;
|
|
136
|
+
const headers = { "Content-Type": "application/json" };
|
|
137
|
+
if (this.config.secret) {
|
|
138
|
+
headers["Authorization"] = `Bearer ${this.config.secret}`;
|
|
139
|
+
}
|
|
140
|
+
if (params?.paymentHeader) {
|
|
141
|
+
headers["X-Payment"] = params.paymentHeader;
|
|
142
|
+
}
|
|
143
|
+
const response = await fetch(url, {
|
|
144
|
+
method: "GET",
|
|
145
|
+
headers
|
|
146
|
+
});
|
|
147
|
+
if (response.status === 402) {
|
|
148
|
+
const x402Response = await response.json().catch(() => ({}));
|
|
149
|
+
const paymentRequirements = x402Response.accepts || [];
|
|
150
|
+
throw new PaymentRequiredError(
|
|
151
|
+
"Payment required",
|
|
152
|
+
paymentRequirements,
|
|
153
|
+
x402Response
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
if (!response.ok) {
|
|
157
|
+
const errorData = await response.json().catch(() => ({}));
|
|
158
|
+
throw new Error(errorData.message || `Request failed: ${response.status}`);
|
|
159
|
+
}
|
|
160
|
+
return response.json();
|
|
161
|
+
}
|
|
84
162
|
};
|
|
85
163
|
var PricesAPI = class {
|
|
86
164
|
constructor(config) {
|
|
@@ -284,15 +362,92 @@ var WebhooksAPI = class {
|
|
|
284
362
|
return this.request("POST", "/payment/v1/webhooks/test", { event, data });
|
|
285
363
|
}
|
|
286
364
|
};
|
|
365
|
+
var PaymentIntentsAPI = class {
|
|
366
|
+
constructor(config) {
|
|
367
|
+
this.request = createRequester(config);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Create a payment intent
|
|
371
|
+
* Use this for simple payments without the full checkout session flow
|
|
372
|
+
*/
|
|
373
|
+
async create(params) {
|
|
374
|
+
return this.request("POST", "/catalog/v1/payment_intents", params);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Retrieve a payment intent
|
|
378
|
+
*/
|
|
379
|
+
async retrieve(id) {
|
|
380
|
+
return this.request("GET", `/catalog/v1/payment_intents/${id}`);
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Confirm a payment intent
|
|
384
|
+
* This triggers the actual payment (and x402 flow if required)
|
|
385
|
+
*/
|
|
386
|
+
async confirm(id) {
|
|
387
|
+
return this.request("POST", `/catalog/v1/payment_intents/${id}/confirm`, {});
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Cancel a payment intent
|
|
391
|
+
*/
|
|
392
|
+
async cancel(id) {
|
|
393
|
+
return this.request("POST", `/catalog/v1/payment_intents/${id}/cancel`, {});
|
|
394
|
+
}
|
|
395
|
+
};
|
|
287
396
|
var PaymentAPI = class {
|
|
288
397
|
constructor(config) {
|
|
289
398
|
this.request = createRequester(config);
|
|
290
399
|
this.checkout = new CheckoutAPI(config);
|
|
400
|
+
this.intents = new PaymentIntentsAPI(config);
|
|
291
401
|
this.links = new LinksAPI(config);
|
|
292
402
|
this.customers = new CustomersAPI(config);
|
|
293
403
|
this.payouts = new PayoutsAPI(config);
|
|
294
404
|
this.webhooks = new WebhooksAPI(config);
|
|
295
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Simple one-liner payment - creates a checkout session with inline product data
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```ts
|
|
411
|
+
* const result = await moneymq.payment.pay({
|
|
412
|
+
* amount: 999,
|
|
413
|
+
* currency: 'usd',
|
|
414
|
+
* productName: 'Pro Plan',
|
|
415
|
+
* productId: 'pro-plan',
|
|
416
|
+
* customer: 'wallet_address',
|
|
417
|
+
* });
|
|
418
|
+
* ```
|
|
419
|
+
*/
|
|
420
|
+
async pay(params) {
|
|
421
|
+
const session = await this.request("POST", "/catalog/v1/checkout/sessions", {
|
|
422
|
+
line_items: [
|
|
423
|
+
{
|
|
424
|
+
price_data: {
|
|
425
|
+
currency: params.currency,
|
|
426
|
+
unit_amount: params.amount,
|
|
427
|
+
product_data: {
|
|
428
|
+
name: params.productName,
|
|
429
|
+
description: params.description,
|
|
430
|
+
metadata: {
|
|
431
|
+
product_id: params.productId || params.productName.toLowerCase().replace(/\s+/g, "-")
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
quantity: 1
|
|
436
|
+
}
|
|
437
|
+
],
|
|
438
|
+
customer: params.customer,
|
|
439
|
+
metadata: params.metadata,
|
|
440
|
+
mode: "payment"
|
|
441
|
+
});
|
|
442
|
+
return {
|
|
443
|
+
sessionId: session.id,
|
|
444
|
+
paymentIntentId: session.payment_intent,
|
|
445
|
+
clientSecret: session.client_secret,
|
|
446
|
+
amount: session.amount_total,
|
|
447
|
+
currency: session.currency,
|
|
448
|
+
status: "requires_confirmation"
|
|
449
|
+
};
|
|
450
|
+
}
|
|
296
451
|
/**
|
|
297
452
|
* Retrieve a payment by ID
|
|
298
453
|
*/
|
|
@@ -313,8 +468,329 @@ var PaymentAPI = class {
|
|
|
313
468
|
}
|
|
314
469
|
};
|
|
315
470
|
|
|
471
|
+
// src/config.ts
|
|
472
|
+
async function fetchConfig(apiUrl) {
|
|
473
|
+
const response = await fetch(`${apiUrl}/config`);
|
|
474
|
+
if (!response.ok) {
|
|
475
|
+
throw new Error(`Failed to fetch config: ${response.status}`);
|
|
476
|
+
}
|
|
477
|
+
return response.json();
|
|
478
|
+
}
|
|
479
|
+
async function getRpcUrl(apiUrl, fallback = "https://api.devnet.solana.com") {
|
|
480
|
+
try {
|
|
481
|
+
const config = await fetchConfig(apiUrl);
|
|
482
|
+
return config.x402.validator.rpcUrl || fallback;
|
|
483
|
+
} catch {
|
|
484
|
+
return fallback;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// src/x402.ts
|
|
489
|
+
var import_x402_fetch = require("x402-fetch");
|
|
490
|
+
var X402API = class {
|
|
491
|
+
constructor(config) {
|
|
492
|
+
this.config = config;
|
|
493
|
+
this.serverConfig = null;
|
|
494
|
+
this.sandboxAccounts = null;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Fetch sandbox accounts from the server
|
|
498
|
+
*/
|
|
499
|
+
async fetchSandboxAccounts() {
|
|
500
|
+
if (this.sandboxAccounts) {
|
|
501
|
+
return this.sandboxAccounts;
|
|
502
|
+
}
|
|
503
|
+
const response = await fetch(`${this.config.endpoint}/sandbox/accounts`);
|
|
504
|
+
if (!response.ok) {
|
|
505
|
+
throw new Error(`Failed to fetch sandbox accounts: ${response.status}`);
|
|
506
|
+
}
|
|
507
|
+
this.sandboxAccounts = await response.json();
|
|
508
|
+
return this.sandboxAccounts;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Get a signer for a sandbox account by tag/label
|
|
512
|
+
*
|
|
513
|
+
* @param params - Parameters containing the wallet tag/label
|
|
514
|
+
* @returns A Signer that can be used directly with wrapFetchWithPayment
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* ```typescript
|
|
518
|
+
* const payer = await moneymq.x402.getSigner({ tag: 'alice' });
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
async getSigner(params) {
|
|
522
|
+
const accounts = await this.fetchSandboxAccounts();
|
|
523
|
+
for (const networkData of Object.values(accounts)) {
|
|
524
|
+
for (const account of networkData.userAccounts) {
|
|
525
|
+
if (account.label === params.tag) {
|
|
526
|
+
if (!account.secretKeyHex) {
|
|
527
|
+
throw new Error(`Account '${params.tag}' does not have a secret key (not locally managed)`);
|
|
528
|
+
}
|
|
529
|
+
return (0, import_x402_fetch.createSigner)("solana", account.secretKeyHex);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
throw new Error(`No sandbox account found with label '${params.tag}'`);
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Get x402 configuration for use with wrapFetchWithPayment
|
|
537
|
+
*
|
|
538
|
+
* @returns Configuration object compatible with x402-fetch
|
|
539
|
+
*
|
|
540
|
+
* @example
|
|
541
|
+
* ```typescript
|
|
542
|
+
* const config = await moneymq.x402.getConfig();
|
|
543
|
+
* const fetchWithPayment = wrapFetchWithPayment(fetch, payer, undefined, undefined, config);
|
|
544
|
+
* ```
|
|
545
|
+
*/
|
|
546
|
+
async getConfig() {
|
|
547
|
+
if (!this.serverConfig) {
|
|
548
|
+
this.serverConfig = await fetchConfig(this.config.endpoint);
|
|
549
|
+
}
|
|
550
|
+
return {
|
|
551
|
+
svmConfig: {
|
|
552
|
+
rpcUrl: this.serverConfig.x402.validator.rpcUrl
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Get the full server configuration
|
|
558
|
+
*
|
|
559
|
+
* @returns The complete server configuration including x402 settings
|
|
560
|
+
*/
|
|
561
|
+
async getServerConfig() {
|
|
562
|
+
if (!this.serverConfig) {
|
|
563
|
+
this.serverConfig = await fetchConfig(this.config.endpoint);
|
|
564
|
+
}
|
|
565
|
+
return this.serverConfig;
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
// src/events.ts
|
|
570
|
+
var EventStream = class {
|
|
571
|
+
constructor(endpoint, options = {}) {
|
|
572
|
+
this.eventSource = null;
|
|
573
|
+
this.state = "disconnected";
|
|
574
|
+
this.reconnectAttempts = 0;
|
|
575
|
+
this.lastEventId = null;
|
|
576
|
+
this.paymentHandlers = /* @__PURE__ */ new Set();
|
|
577
|
+
this.errorHandlers = /* @__PURE__ */ new Set();
|
|
578
|
+
this.stateHandlers = /* @__PURE__ */ new Set();
|
|
579
|
+
this.endpoint = endpoint;
|
|
580
|
+
console.log("[MoneyMQ SDK] EventStream constructor called with options:", JSON.stringify(options));
|
|
581
|
+
this.options = {
|
|
582
|
+
last: options.last ?? 0,
|
|
583
|
+
cursor: options.cursor ?? "",
|
|
584
|
+
streamId: options.streamId ?? "",
|
|
585
|
+
autoReconnect: options.autoReconnect ?? true,
|
|
586
|
+
reconnectDelay: options.reconnectDelay ?? 1e3,
|
|
587
|
+
maxReconnectAttempts: options.maxReconnectAttempts ?? 0
|
|
588
|
+
};
|
|
589
|
+
console.log("[MoneyMQ SDK] Resolved options:", JSON.stringify(this.options));
|
|
590
|
+
if (this.options.cursor && !this.options.streamId) {
|
|
591
|
+
this.lastEventId = this.options.cursor;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Whether this is a stateful stream (server tracks cursor)
|
|
596
|
+
*/
|
|
597
|
+
get isStateful() {
|
|
598
|
+
return this.options.streamId !== "";
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* The stream ID for stateful streams
|
|
602
|
+
*/
|
|
603
|
+
get streamId() {
|
|
604
|
+
return this.options.streamId || null;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Current connection state
|
|
608
|
+
*/
|
|
609
|
+
get connectionState() {
|
|
610
|
+
return this.state;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Current cursor (last received event ID)
|
|
614
|
+
*/
|
|
615
|
+
get cursor() {
|
|
616
|
+
return this.lastEventId;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Whether the stream is currently connected
|
|
620
|
+
*/
|
|
621
|
+
get isConnected() {
|
|
622
|
+
return this.state === "connected";
|
|
623
|
+
}
|
|
624
|
+
on(event, handler) {
|
|
625
|
+
switch (event) {
|
|
626
|
+
case "payment":
|
|
627
|
+
this.paymentHandlers.add(handler);
|
|
628
|
+
return () => this.paymentHandlers.delete(handler);
|
|
629
|
+
case "error":
|
|
630
|
+
this.errorHandlers.add(handler);
|
|
631
|
+
return () => this.errorHandlers.delete(handler);
|
|
632
|
+
case "stateChange":
|
|
633
|
+
this.stateHandlers.add(handler);
|
|
634
|
+
return () => this.stateHandlers.delete(handler);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
off(event, handler) {
|
|
638
|
+
switch (event) {
|
|
639
|
+
case "payment":
|
|
640
|
+
this.paymentHandlers.delete(handler);
|
|
641
|
+
break;
|
|
642
|
+
case "error":
|
|
643
|
+
this.errorHandlers.delete(handler);
|
|
644
|
+
break;
|
|
645
|
+
case "stateChange":
|
|
646
|
+
this.stateHandlers.delete(handler);
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Connect to the event stream
|
|
652
|
+
*/
|
|
653
|
+
connect() {
|
|
654
|
+
if (this.eventSource) {
|
|
655
|
+
this.eventSource.close();
|
|
656
|
+
}
|
|
657
|
+
this.setState("connecting");
|
|
658
|
+
const url = this.buildUrl();
|
|
659
|
+
console.log("[MoneyMQ SDK] Connecting to SSE:", url, "| streamId:", this.options.streamId || "(none)");
|
|
660
|
+
this.eventSource = new EventSource(url);
|
|
661
|
+
this.eventSource.onopen = () => {
|
|
662
|
+
this.setState("connected");
|
|
663
|
+
this.reconnectAttempts = 0;
|
|
664
|
+
};
|
|
665
|
+
this.eventSource.addEventListener("payment", (event) => {
|
|
666
|
+
try {
|
|
667
|
+
const cloudEvent = JSON.parse(event.data);
|
|
668
|
+
this.lastEventId = cloudEvent.id;
|
|
669
|
+
this.emitPayment(cloudEvent);
|
|
670
|
+
} catch (e) {
|
|
671
|
+
this.emitError(new Error(`Failed to parse event: ${e}`));
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
this.eventSource.onerror = () => {
|
|
675
|
+
this.eventSource?.close();
|
|
676
|
+
this.eventSource = null;
|
|
677
|
+
if (this.options.autoReconnect && this.shouldReconnect()) {
|
|
678
|
+
this.scheduleReconnect();
|
|
679
|
+
} else {
|
|
680
|
+
this.setState("disconnected");
|
|
681
|
+
this.emitError(new Error("Connection lost"));
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Disconnect from the event stream
|
|
687
|
+
*/
|
|
688
|
+
disconnect() {
|
|
689
|
+
if (this.eventSource) {
|
|
690
|
+
this.eventSource.close();
|
|
691
|
+
this.eventSource = null;
|
|
692
|
+
}
|
|
693
|
+
this.setState("disconnected");
|
|
694
|
+
this.reconnectAttempts = 0;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Reconnect with a new cursor
|
|
698
|
+
* Useful for resuming from a stored position
|
|
699
|
+
*/
|
|
700
|
+
reconnectFrom(cursor) {
|
|
701
|
+
this.lastEventId = cursor;
|
|
702
|
+
this.disconnect();
|
|
703
|
+
this.connect();
|
|
704
|
+
}
|
|
705
|
+
buildUrl() {
|
|
706
|
+
const params = new URLSearchParams();
|
|
707
|
+
if (this.options.streamId) {
|
|
708
|
+
params.set("stream_id", this.options.streamId);
|
|
709
|
+
if (this.options.last > 0) {
|
|
710
|
+
params.set("last", this.options.last.toString());
|
|
711
|
+
}
|
|
712
|
+
} else {
|
|
713
|
+
if (this.lastEventId) {
|
|
714
|
+
params.set("cursor", this.lastEventId);
|
|
715
|
+
} else if (this.options.last > 0) {
|
|
716
|
+
params.set("last", this.options.last.toString());
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
const queryString = params.toString();
|
|
720
|
+
return queryString ? `${this.endpoint}/events?${queryString}` : `${this.endpoint}/events`;
|
|
721
|
+
}
|
|
722
|
+
setState(state) {
|
|
723
|
+
if (this.state !== state) {
|
|
724
|
+
this.state = state;
|
|
725
|
+
this.stateHandlers.forEach((handler) => handler(state));
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
shouldReconnect() {
|
|
729
|
+
if (this.options.maxReconnectAttempts === 0) return true;
|
|
730
|
+
return this.reconnectAttempts < this.options.maxReconnectAttempts;
|
|
731
|
+
}
|
|
732
|
+
scheduleReconnect() {
|
|
733
|
+
this.setState("reconnecting");
|
|
734
|
+
this.reconnectAttempts++;
|
|
735
|
+
setTimeout(() => {
|
|
736
|
+
if (this.state === "reconnecting") {
|
|
737
|
+
this.connect();
|
|
738
|
+
}
|
|
739
|
+
}, this.options.reconnectDelay);
|
|
740
|
+
}
|
|
741
|
+
emitPayment(event) {
|
|
742
|
+
this.paymentHandlers.forEach((handler) => handler(event));
|
|
743
|
+
}
|
|
744
|
+
emitError(error) {
|
|
745
|
+
this.errorHandlers.forEach((handler) => handler(error));
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
function createEventStream(endpoint, options) {
|
|
749
|
+
return new EventStream(endpoint, options);
|
|
750
|
+
}
|
|
751
|
+
function isPaymentVerificationSucceeded(event) {
|
|
752
|
+
return event.type === "mq.money.payment.verification.succeeded";
|
|
753
|
+
}
|
|
754
|
+
function isPaymentVerificationFailed(event) {
|
|
755
|
+
return event.type === "mq.money.payment.verification.failed";
|
|
756
|
+
}
|
|
757
|
+
function isPaymentSettlementSucceeded(event) {
|
|
758
|
+
return event.type === "mq.money.payment.settlement.succeeded";
|
|
759
|
+
}
|
|
760
|
+
function isPaymentSettlementFailed(event) {
|
|
761
|
+
return event.type === "mq.money.payment.settlement.failed";
|
|
762
|
+
}
|
|
763
|
+
function parseCloudEvent(data) {
|
|
764
|
+
try {
|
|
765
|
+
return JSON.parse(data);
|
|
766
|
+
} catch {
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
function buildEventStreamUrl(endpoint, options) {
|
|
771
|
+
const params = new URLSearchParams();
|
|
772
|
+
if (options?.streamId) {
|
|
773
|
+
params.set("stream_id", options.streamId);
|
|
774
|
+
if (options.last && options.last > 0) {
|
|
775
|
+
params.set("last", options.last.toString());
|
|
776
|
+
}
|
|
777
|
+
} else {
|
|
778
|
+
if (options?.cursor) {
|
|
779
|
+
params.set("cursor", options.cursor);
|
|
780
|
+
} else if (options?.last && options.last > 0) {
|
|
781
|
+
params.set("last", options.last.toString());
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
const queryString = params.toString();
|
|
785
|
+
return queryString ? `${endpoint}/events?${queryString}` : `${endpoint}/events`;
|
|
786
|
+
}
|
|
787
|
+
|
|
316
788
|
// src/client.ts
|
|
317
789
|
var MoneyMQ = class {
|
|
790
|
+
/** MoneyMQ API endpoint */
|
|
791
|
+
get endpoint() {
|
|
792
|
+
return this.config.endpoint;
|
|
793
|
+
}
|
|
318
794
|
constructor(config) {
|
|
319
795
|
this.config = {
|
|
320
796
|
timeout: 3e4,
|
|
@@ -322,6 +798,10 @@ var MoneyMQ = class {
|
|
|
322
798
|
};
|
|
323
799
|
this.catalog = new CatalogAPI(this.config);
|
|
324
800
|
this.payment = new PaymentAPI(this.config);
|
|
801
|
+
this.x402 = new X402API(this.config);
|
|
802
|
+
this.events = {
|
|
803
|
+
stream: (options) => new EventStream(this.config.endpoint, options)
|
|
804
|
+
};
|
|
325
805
|
}
|
|
326
806
|
/**
|
|
327
807
|
* Make an authenticated request to the MoneyMQ API
|
|
@@ -359,27 +839,19 @@ var MoneyMQError = class extends Error {
|
|
|
359
839
|
this.name = "MoneyMQError";
|
|
360
840
|
}
|
|
361
841
|
};
|
|
362
|
-
|
|
363
|
-
// src/config.ts
|
|
364
|
-
async function fetchConfig(apiUrl) {
|
|
365
|
-
const response = await fetch(`${apiUrl}/config`);
|
|
366
|
-
if (!response.ok) {
|
|
367
|
-
throw new Error(`Failed to fetch config: ${response.status}`);
|
|
368
|
-
}
|
|
369
|
-
return response.json();
|
|
370
|
-
}
|
|
371
|
-
async function getRpcUrl(apiUrl, fallback = "https://api.devnet.solana.com") {
|
|
372
|
-
try {
|
|
373
|
-
const config = await fetchConfig(apiUrl);
|
|
374
|
-
return config.x402.validator.rpcUrl || fallback;
|
|
375
|
-
} catch {
|
|
376
|
-
return fallback;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
842
|
// Annotate the CommonJS export names for ESM import in node:
|
|
380
843
|
0 && (module.exports = {
|
|
844
|
+
EventStream,
|
|
381
845
|
MoneyMQ,
|
|
846
|
+
PaymentRequiredError,
|
|
847
|
+
buildEventStreamUrl,
|
|
848
|
+
createEventStream,
|
|
382
849
|
fetchConfig,
|
|
383
|
-
getRpcUrl
|
|
850
|
+
getRpcUrl,
|
|
851
|
+
isPaymentSettlementFailed,
|
|
852
|
+
isPaymentSettlementSucceeded,
|
|
853
|
+
isPaymentVerificationFailed,
|
|
854
|
+
isPaymentVerificationSucceeded,
|
|
855
|
+
parseCloudEvent
|
|
384
856
|
});
|
|
385
857
|
//# sourceMappingURL=index.js.map
|