@cedros/pay-react 1.1.28 → 1.1.29
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/{AISettingsSection-DELur7D2.js → AISettingsSection-B7qrycfY.js} +2 -2
- package/dist/{AISettingsSection-BlIv3CzS.mjs → AISettingsSection-DtAgMsDw.mjs} +6 -4
- package/dist/{AutosaveIndicator-Bed0-ekg.mjs → AutosaveIndicator-BEvABoKU.mjs} +1 -1
- package/dist/AutosaveIndicator-DiyeAg93.js +1 -0
- package/dist/CedrosContext-5Gjveoba.mjs +2555 -0
- package/dist/CedrosContext-CCakH2SZ.js +3 -0
- package/dist/CedrosPayAdminDashboard-CAwEvn66.js +1 -0
- package/dist/CedrosPayAdminDashboard-CBuvNAtB.mjs +250 -0
- package/dist/{ChatLogsSection-v4zwzCTC.mjs → ChatLogsSection-Ber5o8hF.mjs} +19 -17
- package/dist/ChatLogsSection-DLxMMi9I.js +1 -0
- package/dist/ComplianceSection-Buu0zTiL.js +1 -0
- package/dist/{ComplianceSection-CemgfDrL.mjs → ComplianceSection-ZCr0wsvw.mjs} +18 -15
- package/dist/{CryptoButton-BV9owVe2.mjs → CryptoButton-Cl2kZbOP.mjs} +26 -24
- package/dist/CryptoButton-DxFCYDlJ.js +1 -0
- package/dist/CustomersSection-BywmMLur.js +1 -0
- package/dist/{CustomersSection-D_j7OrfS.mjs → CustomersSection-D9UknSKC.mjs} +21 -19
- package/dist/{DisputesSection-BcAbXp3K.mjs → DisputesSection-C_eySK-W.mjs} +19 -17
- package/dist/DisputesSection-DwkHGv2a.js +1 -0
- package/dist/Dropdown-B90Zabxr.mjs +111 -0
- package/dist/Dropdown-CtY91emj.js +1 -0
- package/dist/ErrorBanner-CZXsHi3H.mjs +22 -0
- package/dist/ErrorBanner-Cx2dUhps.js +1 -0
- package/dist/{FAQSection-Dn38OhB_.mjs → FAQSection-Bv_Hdt8B.mjs} +8 -6
- package/dist/FAQSection-DlPLnIJD.js +1 -0
- package/dist/ImagesSection-B4Jzet79.js +1 -0
- package/dist/{ImagesSection-Ctw9Icym.mjs → ImagesSection-DpdXQ6qu.mjs} +6 -4
- package/dist/InventorySection-BgRdpn1l.js +1 -0
- package/dist/{InventorySection-DmhjUlRZ.mjs → InventorySection-DZMu9DMw.mjs} +25 -23
- package/dist/MessagingSection-CxV-pf-f.js +1 -0
- package/dist/{MessagingSection-B1FaGxkp.mjs → MessagingSection-D_cOBfFt.mjs} +5 -4
- package/dist/OrdersSection-BbAX79Ff.js +1 -0
- package/dist/{OrdersSection-Bj8bPdg8.mjs → OrdersSection-wfPavit9.mjs} +27 -24
- package/dist/PaymentSettingsSection-BdBDgaRg.js +1 -0
- package/dist/PaymentSettingsSection-DunzBo9n.mjs +648 -0
- package/dist/ReturnsSection-7k4LZ8yp.js +1 -0
- package/dist/{ReturnsSection-BC0L8r2e.mjs → ReturnsSection-B4FL7bUv.mjs} +11 -9
- package/dist/{SettingsSection-vdYFSNxB.js → SettingsSection-Cz2Yjdhr.js} +1 -1
- package/dist/{SettingsSection-KYdEizq_.mjs → SettingsSection-DoeNDbqd.mjs} +1 -1
- package/dist/{ShippingSection-BOgto6_9.mjs → ShippingSection-BlVsYC6B.mjs} +5 -3
- package/dist/ShippingSection-C-HI8rOb.js +1 -0
- package/dist/{SingleCategorySettings-suJ8z9d8.mjs → SingleCategorySettings-B406nnF-.mjs} +143 -140
- package/dist/SingleCategorySettings-BqC2UXt3.js +3 -0
- package/dist/StatsBar-D4v-I_Dj.mjs +25 -0
- package/dist/StatsBar-m6GSRNxs.js +1 -0
- package/dist/StorefrontSection-Axvh_KeS.js +1 -0
- package/dist/{StorefrontSection-BRvIGBEJ.mjs → StorefrontSection-BK_rhrAi.mjs} +121 -119
- package/dist/{SubscriptionsSection-D60qrX9a.mjs → SubscriptionsSection-D8V9RBv-.mjs} +11 -9
- package/dist/SubscriptionsSection-EeULMWIB.js +1 -0
- package/dist/{TaxSection-C7-pv-Rl.mjs → TaxSection-Cj6TXL6x.mjs} +23 -21
- package/dist/TaxSection-CzHPhaHl.js +1 -0
- package/dist/ThemeContext-CFXyYx7A.js +1 -0
- package/dist/ThemeContext-l0bqcOGW.mjs +126 -0
- package/dist/Token22Section-DqRKVG_G.js +1 -0
- package/dist/{Token22Section-CrHLQ0EB.mjs → Token22Section-DtYAcT54.mjs} +7 -6
- package/dist/{WalletManager-BIwH8Dw_.mjs → WalletManager-D-eoqUDy.mjs} +21 -19
- package/dist/WalletManager-DXChB9LA.js +1 -0
- package/dist/WebhooksSection-D--iPZuM.js +1 -0
- package/dist/{WebhooksSection-COPW4Ec0.mjs → WebhooksSection-DBAIxtBy.mjs} +40 -38
- package/dist/admin.d.ts +2 -0
- package/dist/admin.js +1 -0
- package/dist/admin.mjs +8 -0
- package/dist/configApi-BS5UJfzm.js +1 -0
- package/dist/{configApi-6XhAJGKX.mjs → configApi-BUXZOMWK.mjs} +57 -3
- package/dist/crypto-only.js +1 -1
- package/dist/crypto-only.mjs +214 -202
- package/dist/dateHelpers-BKW_lGND.js +1 -0
- package/dist/dateHelpers-yvPkofYQ.mjs +6 -0
- package/dist/fetchWithTimeout-CG0EKbhf.js +1 -0
- package/dist/fetchWithTimeout-DmMOwL0Q.mjs +195 -0
- package/dist/index-9QF_UfSN.mjs +18668 -0
- package/dist/index-Cq9ya93W.js +84 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +74 -64
- package/dist/safeHref-DqJPLPl5.mjs +12 -0
- package/dist/safeHref-DyHIpVjY.js +1 -0
- package/dist/sectionIds-B_tFiNvF.js +1 -0
- package/dist/sectionIds-DBavltrL.mjs +359 -0
- package/dist/sections-BHph7CYj.mjs +9 -0
- package/dist/sections-C2zEJr5G.js +1 -0
- package/dist/sections-more-C1VNVwkp.js +1 -0
- package/dist/sections-more-CMFgfU4d.mjs +3082 -0
- package/dist/src/admin/index.d.ts +3 -3
- package/dist/src/admin/index.d.ts.map +1 -1
- package/dist/src/admin/plugin.d.ts.map +1 -1
- package/dist/src/admin/types.d.ts +2 -6
- package/dist/src/admin/types.d.ts.map +1 -1
- package/dist/src/admin.d.ts +9 -0
- package/dist/src/admin.d.ts.map +1 -0
- package/dist/src/components/admin/LazyCedrosPayAdminDashboard.d.ts +4 -0
- package/dist/src/components/admin/LazyCedrosPayAdminDashboard.d.ts.map +1 -0
- package/dist/src/components/admin/PaymentReadinessChecklist.d.ts +9 -0
- package/dist/src/components/admin/PaymentReadinessChecklist.d.ts.map +1 -0
- package/dist/src/components/admin/PaymentSettingsSection.d.ts.map +1 -1
- package/dist/src/components/admin/PaymentSetupGuide.d.ts +6 -0
- package/dist/src/components/admin/PaymentSetupGuide.d.ts.map +1 -0
- package/dist/src/components/admin/ProductsSection.d.ts.map +1 -1
- package/dist/src/components/admin/configApi.d.ts +1 -1
- package/dist/src/components/admin/configApi.d.ts.map +1 -1
- package/dist/src/components/admin/icons.d.ts +3 -50
- package/dist/src/components/admin/icons.d.ts.map +1 -1
- package/dist/src/components/admin/index.d.ts +1 -1
- package/dist/src/components/admin/index.d.ts.map +1 -1
- package/dist/src/components/admin/types.d.ts +43 -0
- package/dist/src/components/admin/types.d.ts.map +1 -1
- package/dist/src/context/CedrosContext.d.ts +2 -0
- package/dist/src/context/CedrosContext.d.ts.map +1 -1
- package/dist/src/ecommerce/__tests__/featureFlags.test.d.ts +2 -0
- package/dist/src/ecommerce/__tests__/featureFlags.test.d.ts.map +1 -0
- package/dist/src/ecommerce/adapters/paywall/paywallAdapter.d.ts.map +1 -1
- package/dist/src/ecommerce/components/general/ErrorBoundary.d.ts +1 -1
- package/dist/src/ecommerce/components/ui/button.d.ts +1 -1
- package/dist/src/ecommerce/components/ui/sheet.d.ts +1 -1
- package/dist/src/ecommerce/config/context.d.ts +2 -0
- package/dist/src/ecommerce/config/context.d.ts.map +1 -1
- package/dist/src/ecommerce/config/types.d.ts +2 -0
- package/dist/src/ecommerce/config/types.d.ts.map +1 -1
- package/dist/src/ecommerce/index.d.ts +2 -0
- package/dist/src/ecommerce/index.d.ts.map +1 -1
- package/dist/src/featureFlags.d.ts +41 -0
- package/dist/src/featureFlags.d.ts.map +1 -0
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/managers/StripeManager.d.ts.map +1 -1
- package/dist/src/managers/SubscriptionManager.d.ts +1 -0
- package/dist/src/managers/SubscriptionManager.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +14 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/subscription.d.ts +47 -1
- package/dist/src/types/subscription.d.ts.map +1 -1
- package/dist/src/utils/validateConfig.d.ts.map +1 -1
- package/dist/stripe-only.js +1 -1
- package/dist/stripe-only.mjs +35 -33
- package/dist/styles--fxb3lCl.js +1 -0
- package/dist/{styles-D4SQkuV3.mjs → styles-DGagylUj.mjs} +53 -51
- package/dist/testing/index.js +1 -1
- package/dist/testing/index.mjs +1 -1
- package/dist/tokenMintValidator-DAjQld0r.mjs +98 -0
- package/dist/tokenMintValidator-DNBhoefh.js +4 -0
- package/dist/{walletPool-DE-t1wSW.mjs → walletPool-9MylB2QK.mjs} +1 -1
- package/dist/walletPool-BjTXX6Vn.js +1 -0
- package/package.json +3 -3
- package/dist/AutosaveIndicator-Dn_qA2hK.js +0 -1
- package/dist/CedrosContext-C2RjHLaQ.js +0 -6
- package/dist/CedrosContext-CY6zvjvJ.mjs +0 -2801
- package/dist/ChatLogsSection-BH5tLA4T.js +0 -1
- package/dist/ComplianceSection-DP2a9-S0.js +0 -1
- package/dist/CryptoButton-DpiCnyXE.js +0 -1
- package/dist/CustomersSection-CBwy_waO.js +0 -1
- package/dist/DisputesSection-BLjIk60n.js +0 -1
- package/dist/FAQSection-wNeH0i6Q.js +0 -1
- package/dist/ImagesSection-0ZzKlzMJ.js +0 -1
- package/dist/InventorySection-zV6lTmue.js +0 -1
- package/dist/MessagingSection-B_wdFR0j.js +0 -1
- package/dist/OrdersSection-Dw2FX-1d.js +0 -1
- package/dist/PaymentSettingsSection-BYF4D-GR.js +0 -1
- package/dist/PaymentSettingsSection-EnMxeWjv.mjs +0 -94
- package/dist/ReturnsSection-D_pJVxuG.js +0 -1
- package/dist/ShippingSection-1DRSTu49.js +0 -1
- package/dist/SingleCategorySettings-DwCnBdRf.js +0 -3
- package/dist/StorefrontSection-RumGkb3C.js +0 -1
- package/dist/SubscriptionsSection-C2aLLn7L.js +0 -1
- package/dist/TaxSection-Dt1DnM51.js +0 -1
- package/dist/Token22Section-DY3mUwTY.js +0 -1
- package/dist/WalletManager-B3UdQ5pQ.js +0 -1
- package/dist/WebhooksSection-CKeiJ7Py.js +0 -1
- package/dist/configApi-DkduMQg1.js +0 -1
- package/dist/index-C0g-JxJk.js +0 -84
- package/dist/index-DXnuQp5x.mjs +0 -22128
- package/dist/sections-C1NpK7hk.mjs +0 -9
- package/dist/sections-DVVSZBhW.js +0 -1
- package/dist/styles-BT4bhFey.js +0 -1
- package/dist/walletPool-IS7R3MR1.js +0 -1
|
@@ -1,2801 +0,0 @@
|
|
|
1
|
-
import { jsx as J } from "react/jsx-runtime";
|
|
2
|
-
import { useContext as se, useState as U, useRef as ve, useEffect as F, useMemo as ae, createContext as Ee } from "react";
|
|
3
|
-
import { g as k } from "./uuid-_z3jSatJ.mjs";
|
|
4
|
-
var Ce = "https://js.stripe.com/v3", Qe = /^https:\/\/js\.stripe\.com\/v3\/?(\?.*)?$/;
|
|
5
|
-
var We = function() {
|
|
6
|
-
for (var e = document.querySelectorAll('script[src^="'.concat(Ce, '"]')), r = 0; r < e.length; r++) {
|
|
7
|
-
var a = e[r];
|
|
8
|
-
if (Qe.test(a.src))
|
|
9
|
-
return a;
|
|
10
|
-
}
|
|
11
|
-
return null;
|
|
12
|
-
}, de = function(e) {
|
|
13
|
-
var r = "", a = document.createElement("script");
|
|
14
|
-
a.src = "".concat(Ce).concat(r);
|
|
15
|
-
var n = document.head || document.body;
|
|
16
|
-
if (!n)
|
|
17
|
-
throw new Error("Expected document.body not to be null. Stripe.js requires a <body> element.");
|
|
18
|
-
return n.appendChild(a), a;
|
|
19
|
-
}, Ke = function(e, r) {
|
|
20
|
-
!e || !e._registerWrapper || e._registerWrapper({
|
|
21
|
-
name: "stripe-js",
|
|
22
|
-
version: "4.6.0",
|
|
23
|
-
startTime: r
|
|
24
|
-
});
|
|
25
|
-
}, q = null, W = null, K = null, Ge = function(e) {
|
|
26
|
-
return function() {
|
|
27
|
-
e(new Error("Failed to load Stripe.js"));
|
|
28
|
-
};
|
|
29
|
-
}, Ve = function(e, r) {
|
|
30
|
-
return function() {
|
|
31
|
-
window.Stripe ? e(window.Stripe) : r(new Error("Stripe.js not available"));
|
|
32
|
-
};
|
|
33
|
-
}, Je = function(e) {
|
|
34
|
-
return q !== null ? q : (q = new Promise(function(r, a) {
|
|
35
|
-
if (typeof window > "u" || typeof document > "u") {
|
|
36
|
-
r(null);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (window.Stripe) {
|
|
40
|
-
r(window.Stripe);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
var n = We();
|
|
45
|
-
if (!(n && e)) {
|
|
46
|
-
if (!n)
|
|
47
|
-
n = de(e);
|
|
48
|
-
else if (n && K !== null && W !== null) {
|
|
49
|
-
var i;
|
|
50
|
-
n.removeEventListener("load", K), n.removeEventListener("error", W), (i = n.parentNode) === null || i === void 0 || i.removeChild(n), n = de(e);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
K = Ve(r, a), W = Ge(a), n.addEventListener("load", K), n.addEventListener("error", W);
|
|
54
|
-
} catch (o) {
|
|
55
|
-
a(o);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
}), q.catch(function(r) {
|
|
59
|
-
return q = null, Promise.reject(r);
|
|
60
|
-
}));
|
|
61
|
-
}, Ye = function(e, r, a) {
|
|
62
|
-
if (e === null)
|
|
63
|
-
return null;
|
|
64
|
-
var n = e.apply(void 0, r);
|
|
65
|
-
return Ke(n, a), n;
|
|
66
|
-
}, j, Pe = !1, Se = function() {
|
|
67
|
-
return j || (j = Je(null).catch(function(e) {
|
|
68
|
-
return j = null, Promise.reject(e);
|
|
69
|
-
}), j);
|
|
70
|
-
};
|
|
71
|
-
Promise.resolve().then(function() {
|
|
72
|
-
return Se();
|
|
73
|
-
}).catch(function(t) {
|
|
74
|
-
Pe || console.warn(t);
|
|
75
|
-
});
|
|
76
|
-
var Te = function() {
|
|
77
|
-
for (var e = arguments.length, r = new Array(e), a = 0; a < e; a++)
|
|
78
|
-
r[a] = arguments[a];
|
|
79
|
-
Pe = !0;
|
|
80
|
-
var n = Date.now();
|
|
81
|
-
return Se().then(function(i) {
|
|
82
|
-
return Ye(i, r, n);
|
|
83
|
-
});
|
|
84
|
-
}, $e = /* @__PURE__ */ ((t) => (t[t.DEBUG = 0] = "DEBUG", t[t.INFO = 1] = "INFO", t[t.WARN = 2] = "WARN", t[t.ERROR = 3] = "ERROR", t[t.SILENT = 4] = "SILENT", t))($e || {});
|
|
85
|
-
class xe {
|
|
86
|
-
config;
|
|
87
|
-
constructor(e) {
|
|
88
|
-
this.config = e;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Update the log level dynamically
|
|
92
|
-
*/
|
|
93
|
-
setLevel(e) {
|
|
94
|
-
this.config.level = e;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Get the current log level
|
|
98
|
-
*/
|
|
99
|
-
getLevel() {
|
|
100
|
-
return this.config.level;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Debug-level logging (most verbose)
|
|
104
|
-
* Use for detailed debugging information
|
|
105
|
-
*/
|
|
106
|
-
debug(...e) {
|
|
107
|
-
this.config.level <= 0 && this.log("DEBUG", console.log, e);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Info-level logging
|
|
111
|
-
* Use for general informational messages
|
|
112
|
-
*/
|
|
113
|
-
info(...e) {
|
|
114
|
-
this.config.level <= 1 && this.log("INFO", console.info, e);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Warning-level logging
|
|
118
|
-
* Use for potentially problematic situations
|
|
119
|
-
*/
|
|
120
|
-
warn(...e) {
|
|
121
|
-
this.config.level <= 2 && this.log("WARN", console.warn, e);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Error-level logging
|
|
125
|
-
* Use for error conditions
|
|
126
|
-
*/
|
|
127
|
-
error(...e) {
|
|
128
|
-
this.config.level <= 3 && this.log("ERROR", console.error, e);
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Internal log method with formatting
|
|
132
|
-
*/
|
|
133
|
-
log(e, r, a) {
|
|
134
|
-
const n = this.config.prefix ? `${this.config.prefix} ` : "", i = (/* @__PURE__ */ new Date()).toISOString();
|
|
135
|
-
r(`[${i}] ${n}[${e}]`, ...a);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
const Xe = () => typeof process < "u" && process.env.NODE_ENV === "development" ? 0 : 2;
|
|
139
|
-
let Y = null;
|
|
140
|
-
function l() {
|
|
141
|
-
return Y || (Y = new xe({
|
|
142
|
-
level: Xe(),
|
|
143
|
-
prefix: "[CedrosPay]"
|
|
144
|
-
})), Y;
|
|
145
|
-
}
|
|
146
|
-
function Ze(t) {
|
|
147
|
-
Y = t;
|
|
148
|
-
}
|
|
149
|
-
function et(t) {
|
|
150
|
-
return new xe(t);
|
|
151
|
-
}
|
|
152
|
-
function O(t, e) {
|
|
153
|
-
return t instanceof Error ? t.message : typeof t == "string" ? t : e;
|
|
154
|
-
}
|
|
155
|
-
const tt = {
|
|
156
|
-
service_unavailable: "Service temporarily unavailable. Please try again later or contact support.",
|
|
157
|
-
server_insufficient_funds: "Service temporarily unavailable. Please try again later or contact support.",
|
|
158
|
-
insufficient_funds_token: "Insufficient token balance in your wallet. Please add more tokens and try again.",
|
|
159
|
-
insufficient_funds_sol: "Insufficient SOL for transaction fees. Please add some SOL to your wallet and try again.",
|
|
160
|
-
insufficient_amount: "Payment amount is insufficient. Please check the required amount.",
|
|
161
|
-
invalid_signature: "Transaction signature is invalid. Please try again.",
|
|
162
|
-
send_failed: "Failed to send transaction. Please try again or contact support.",
|
|
163
|
-
timeout: "Transaction timed out. Please check the blockchain explorer or try again."
|
|
164
|
-
};
|
|
165
|
-
async function w(t, e, r = !1) {
|
|
166
|
-
const a = typeof t.clone == "function", n = a ? t.clone() : void 0;
|
|
167
|
-
try {
|
|
168
|
-
const i = await t.json();
|
|
169
|
-
if (r && i.verificationError) {
|
|
170
|
-
l().debug(`Payment verification failed: ${i.verificationError.code}`);
|
|
171
|
-
const o = i.verificationError.code;
|
|
172
|
-
return tt[o] || i.verificationError.message || e;
|
|
173
|
-
}
|
|
174
|
-
return typeof i.error == "string" ? i.error : i.error && typeof i.error == "object" && "message" in i.error ? i.error.message : e;
|
|
175
|
-
} catch {
|
|
176
|
-
if (n)
|
|
177
|
-
try {
|
|
178
|
-
const i = await n.text();
|
|
179
|
-
if (i) return i;
|
|
180
|
-
} catch {
|
|
181
|
-
}
|
|
182
|
-
if (!a && typeof t.text == "function")
|
|
183
|
-
try {
|
|
184
|
-
const i = await t.text();
|
|
185
|
-
if (i) return i;
|
|
186
|
-
} catch {
|
|
187
|
-
}
|
|
188
|
-
return e;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
const rt = 15e3;
|
|
192
|
-
async function p(t, e = {}, r = rt) {
|
|
193
|
-
const a = new AbortController(), n = e.signal;
|
|
194
|
-
if (n?.aborted)
|
|
195
|
-
throw a.abort(), new DOMException("The operation was aborted", "AbortError");
|
|
196
|
-
const i = setTimeout(() => a.abort(), r);
|
|
197
|
-
let o = null;
|
|
198
|
-
n && (o = () => a.abort(), n.addEventListener("abort", o));
|
|
199
|
-
try {
|
|
200
|
-
return await fetch(t, {
|
|
201
|
-
...e,
|
|
202
|
-
signal: a.signal
|
|
203
|
-
});
|
|
204
|
-
} catch (s) {
|
|
205
|
-
throw s instanceof Error && s.name === "AbortError" ? n?.aborted ? s : new Error(`Request timeout after ${r}ms`) : s;
|
|
206
|
-
} finally {
|
|
207
|
-
clearTimeout(i), n && o && n.removeEventListener("abort", o);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
function I(t) {
|
|
211
|
-
const { maxRequests: e, windowMs: r } = t;
|
|
212
|
-
let a = e, n = Date.now();
|
|
213
|
-
const i = e / r;
|
|
214
|
-
function o() {
|
|
215
|
-
const h = Date.now(), y = h - n;
|
|
216
|
-
if (y > 0) {
|
|
217
|
-
const d = y * i;
|
|
218
|
-
a = Math.min(e, a + d), n = h;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function s() {
|
|
222
|
-
return o(), a >= 1 ? (a -= 1, !0) : !1;
|
|
223
|
-
}
|
|
224
|
-
function c() {
|
|
225
|
-
return o(), Math.floor(a);
|
|
226
|
-
}
|
|
227
|
-
function u() {
|
|
228
|
-
if (o(), a >= 1)
|
|
229
|
-
return 0;
|
|
230
|
-
const y = (1 - a) / i;
|
|
231
|
-
return Math.ceil(y);
|
|
232
|
-
}
|
|
233
|
-
function f() {
|
|
234
|
-
a = e, n = Date.now();
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
tryConsume: s,
|
|
238
|
-
getAvailableTokens: c,
|
|
239
|
-
getTimeUntilRefill: u,
|
|
240
|
-
reset: f
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
const B = {
|
|
244
|
-
/** 10 requests per minute - recommended for payment requests */
|
|
245
|
-
PAYMENT: { maxRequests: 10, windowMs: 6e4 },
|
|
246
|
-
/** 30 requests per minute - for quote fetching */
|
|
247
|
-
QUOTE: { maxRequests: 30, windowMs: 6e4 },
|
|
248
|
-
/** 5 requests per minute - strict limit for sensitive operations */
|
|
249
|
-
STRICT: { maxRequests: 5, windowMs: 6e4 },
|
|
250
|
-
/** 100 requests per minute - permissive for UI interactions */
|
|
251
|
-
PERMISSIVE: { maxRequests: 100, windowMs: 6e4 }
|
|
252
|
-
};
|
|
253
|
-
var at = /* @__PURE__ */ ((t) => (t.CLOSED = "CLOSED", t.OPEN = "OPEN", t.HALF_OPEN = "HALF_OPEN", t))(at || {});
|
|
254
|
-
class g extends Error {
|
|
255
|
-
constructor(e) {
|
|
256
|
-
super(e), this.name = "CircuitBreakerOpenError";
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
function Q(t) {
|
|
260
|
-
const { failureThreshold: e, timeout: r, failureWindow: a = r * 2, name: n = "circuit-breaker" } = t;
|
|
261
|
-
let i = "CLOSED", o = [], s = 0, c = 0, u = null, f = null, h = null, y = !1;
|
|
262
|
-
function d() {
|
|
263
|
-
const R = Date.now() - a;
|
|
264
|
-
o = o.filter((C) => C > R);
|
|
265
|
-
}
|
|
266
|
-
function m() {
|
|
267
|
-
i === "OPEN" && h !== null && Date.now() >= h && (l().debug(`[CircuitBreaker:${n}] Transitioning OPEN → HALF_OPEN (timeout expired)`), i = "HALF_OPEN", h = null);
|
|
268
|
-
}
|
|
269
|
-
function A() {
|
|
270
|
-
f = Date.now(), s++, i === "HALF_OPEN" ? (l().debug(`[CircuitBreaker:${n}] Success in HALF_OPEN → CLOSED`), i = "CLOSED", o = []) : i === "CLOSED" && (o = []);
|
|
271
|
-
}
|
|
272
|
-
function b(R) {
|
|
273
|
-
const C = Date.now();
|
|
274
|
-
u = C, o.push(C), d();
|
|
275
|
-
const Z = o.length;
|
|
276
|
-
l().warn(`[CircuitBreaker:${n}] Failure recorded (${Z}/${e}):`, R.message), i === "HALF_OPEN" ? (l().warn(`[CircuitBreaker:${n}] Failed in HALF_OPEN → OPEN`), i = "OPEN", h = C + r) : i === "CLOSED" && Z >= e && (l().error(`[CircuitBreaker:${n}] Failure threshold reached (${Z}) → OPEN`), i = "OPEN", h = C + r);
|
|
277
|
-
}
|
|
278
|
-
async function x(R) {
|
|
279
|
-
if (m(), i === "OPEN") {
|
|
280
|
-
c++;
|
|
281
|
-
const C = h ? Math.ceil((h - Date.now()) / 1e3) : 0;
|
|
282
|
-
throw new g(
|
|
283
|
-
`Circuit breaker is OPEN. Service is unavailable. Retry in ${C}s.`
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
if (i === "HALF_OPEN" && y)
|
|
287
|
-
throw c++, new g(
|
|
288
|
-
"Circuit breaker is HALF_OPEN. A probe request is already in progress."
|
|
289
|
-
);
|
|
290
|
-
i === "HALF_OPEN" && (y = !0);
|
|
291
|
-
try {
|
|
292
|
-
const C = await R();
|
|
293
|
-
return A(), C;
|
|
294
|
-
} catch (C) {
|
|
295
|
-
throw b(C instanceof Error ? C : new Error(String(C))), C;
|
|
296
|
-
} finally {
|
|
297
|
-
y && (y = !1);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
function D() {
|
|
301
|
-
return m(), i;
|
|
302
|
-
}
|
|
303
|
-
function M() {
|
|
304
|
-
return m(), d(), {
|
|
305
|
-
state: i,
|
|
306
|
-
failures: o.length,
|
|
307
|
-
successes: s,
|
|
308
|
-
rejections: c,
|
|
309
|
-
lastFailureTime: u,
|
|
310
|
-
lastSuccessTime: f
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
function S() {
|
|
314
|
-
l().debug(`[CircuitBreaker:${n}] Manual reset → CLOSED`), i = "CLOSED", o = [], s = 0, c = 0, u = null, f = null, h = null;
|
|
315
|
-
}
|
|
316
|
-
function _() {
|
|
317
|
-
l().warn(`[CircuitBreaker:${n}] Manual trip → OPEN`), i = "OPEN", h = Date.now() + r;
|
|
318
|
-
}
|
|
319
|
-
return {
|
|
320
|
-
execute: x,
|
|
321
|
-
getState: D,
|
|
322
|
-
getStats: M,
|
|
323
|
-
reset: S,
|
|
324
|
-
trip: _
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
const Yt = {
|
|
328
|
-
/** Strict: Opens quickly (3 failures), long timeout (60s) */
|
|
329
|
-
STRICT: { failureThreshold: 3, timeout: 6e4 },
|
|
330
|
-
/** Standard: Balanced settings (5 failures, 30s timeout) */
|
|
331
|
-
STANDARD: { failureThreshold: 5, timeout: 3e4 },
|
|
332
|
-
/** Lenient: Tolerates more failures (10 failures, 15s timeout) */
|
|
333
|
-
LENIENT: { failureThreshold: 10, timeout: 15e3 }
|
|
334
|
-
}, nt = {
|
|
335
|
-
// ===== PAYMENT VERIFICATION ERRORS (402) =====
|
|
336
|
-
invalid_payment_proof: {
|
|
337
|
-
message: "Payment verification failed",
|
|
338
|
-
action: "Please try your payment again. If this continues, contact support.",
|
|
339
|
-
technicalHint: "Invalid payment proof format"
|
|
340
|
-
},
|
|
341
|
-
invalid_signature: {
|
|
342
|
-
message: "Transaction signature is invalid",
|
|
343
|
-
action: "Please approve the transaction in your wallet and try again.",
|
|
344
|
-
technicalHint: "Transaction signature verification failed"
|
|
345
|
-
},
|
|
346
|
-
invalid_transaction: {
|
|
347
|
-
message: "Transaction format is invalid",
|
|
348
|
-
action: "Please try your payment again. If this continues, try updating your wallet app.",
|
|
349
|
-
technicalHint: "Malformed transaction structure"
|
|
350
|
-
},
|
|
351
|
-
transaction_not_found: {
|
|
352
|
-
message: "Transaction not found on the blockchain",
|
|
353
|
-
action: "Your transaction may still be processing. Please wait a moment and check your wallet, or try again.",
|
|
354
|
-
technicalHint: "Transaction signature not found on-chain"
|
|
355
|
-
},
|
|
356
|
-
transaction_not_confirmed: {
|
|
357
|
-
message: "Transaction is still processing",
|
|
358
|
-
action: "Please wait a moment for the blockchain to confirm your transaction, then try again.",
|
|
359
|
-
technicalHint: "Transaction not yet confirmed"
|
|
360
|
-
},
|
|
361
|
-
transaction_failed: {
|
|
362
|
-
message: "Transaction failed on the blockchain",
|
|
363
|
-
action: "Check your wallet for details. You may need to adjust your transaction settings or add more SOL for fees.",
|
|
364
|
-
technicalHint: "On-chain transaction failure"
|
|
365
|
-
},
|
|
366
|
-
transaction_expired: {
|
|
367
|
-
message: "Transaction took too long to process",
|
|
368
|
-
action: "Please try your payment again. Consider increasing transaction priority if your wallet supports it.",
|
|
369
|
-
technicalHint: "Transaction blockhash expired"
|
|
370
|
-
},
|
|
371
|
-
invalid_recipient: {
|
|
372
|
-
message: "Payment was sent to the wrong address",
|
|
373
|
-
action: "Please try again and ensure you approve the correct transaction in your wallet.",
|
|
374
|
-
technicalHint: "Recipient address mismatch"
|
|
375
|
-
},
|
|
376
|
-
invalid_sender: {
|
|
377
|
-
message: "Payment sender wallet is invalid",
|
|
378
|
-
action: "Please reconnect your wallet and try again.",
|
|
379
|
-
technicalHint: "Sender address validation failed"
|
|
380
|
-
},
|
|
381
|
-
unauthorized_refund_issuer: {
|
|
382
|
-
message: "You are not authorized to issue refunds",
|
|
383
|
-
action: "Only authorized accounts can process refunds. Please contact support if you believe this is an error.",
|
|
384
|
-
technicalHint: "Refund issuer not in authorized list"
|
|
385
|
-
},
|
|
386
|
-
amount_below_minimum: {
|
|
387
|
-
message: "Payment amount is too low",
|
|
388
|
-
action: "Please check the required amount and try again.",
|
|
389
|
-
technicalHint: "Amount below minimum threshold"
|
|
390
|
-
},
|
|
391
|
-
amount_mismatch: {
|
|
392
|
-
message: "Payment amount does not match the quote",
|
|
393
|
-
action: "The price may have changed. Please refresh and try your payment again.",
|
|
394
|
-
technicalHint: "Amount does not match quote"
|
|
395
|
-
},
|
|
396
|
-
insufficient_funds_sol: {
|
|
397
|
-
message: "Not enough SOL for transaction fees",
|
|
398
|
-
action: "Add at least 0.001 SOL to your wallet to cover network fees, then try again.",
|
|
399
|
-
technicalHint: "Insufficient SOL balance for fees"
|
|
400
|
-
},
|
|
401
|
-
insufficient_funds_token: {
|
|
402
|
-
message: "Insufficient balance in your wallet",
|
|
403
|
-
action: "Add more funds to your wallet and try again.",
|
|
404
|
-
technicalHint: "Insufficient token balance"
|
|
405
|
-
},
|
|
406
|
-
invalid_token_mint: {
|
|
407
|
-
message: "Incorrect payment token",
|
|
408
|
-
action: "Please pay with the correct token as shown in the payment details.",
|
|
409
|
-
technicalHint: "Token mint address mismatch"
|
|
410
|
-
},
|
|
411
|
-
not_spl_transfer: {
|
|
412
|
-
message: "Transaction is not a valid token transfer",
|
|
413
|
-
action: "Please ensure you are sending the correct token type from your wallet.",
|
|
414
|
-
technicalHint: "Transaction is not an SPL token transfer"
|
|
415
|
-
},
|
|
416
|
-
missing_token_account: {
|
|
417
|
-
message: "Token account not found",
|
|
418
|
-
action: "Your wallet may need to create a token account first. Try again or use a different wallet.",
|
|
419
|
-
technicalHint: "Associated token account does not exist"
|
|
420
|
-
},
|
|
421
|
-
invalid_token_program: {
|
|
422
|
-
message: "Invalid token program",
|
|
423
|
-
action: "Please try your payment again. If this continues, try using a different wallet.",
|
|
424
|
-
technicalHint: "Token program ID mismatch"
|
|
425
|
-
},
|
|
426
|
-
missing_memo: {
|
|
427
|
-
message: "Payment memo is required but was not included",
|
|
428
|
-
action: "Please try your payment again and ensure transaction details are approved in your wallet.",
|
|
429
|
-
technicalHint: "Required memo instruction missing"
|
|
430
|
-
},
|
|
431
|
-
invalid_memo: {
|
|
432
|
-
message: "Payment memo format is invalid",
|
|
433
|
-
action: "Please try your payment again.",
|
|
434
|
-
technicalHint: "Memo does not match expected format"
|
|
435
|
-
},
|
|
436
|
-
payment_already_used: {
|
|
437
|
-
message: "This payment has already been processed",
|
|
438
|
-
action: "Check your transaction history. If you need to make another payment, please start a new transaction.",
|
|
439
|
-
technicalHint: "Payment signature already recorded"
|
|
440
|
-
},
|
|
441
|
-
signature_reused: {
|
|
442
|
-
message: "Transaction signature has already been used",
|
|
443
|
-
action: "Please create a new payment transaction.",
|
|
444
|
-
technicalHint: "Duplicate signature detected"
|
|
445
|
-
},
|
|
446
|
-
quote_expired: {
|
|
447
|
-
message: "Payment quote has expired",
|
|
448
|
-
action: "Prices are updated frequently. Please refresh and try your payment again.",
|
|
449
|
-
technicalHint: "Quote timestamp expired"
|
|
450
|
-
},
|
|
451
|
-
// ===== VALIDATION ERRORS (400) =====
|
|
452
|
-
missing_field: {
|
|
453
|
-
message: "Required information is missing",
|
|
454
|
-
action: "Please check all required fields and try again.",
|
|
455
|
-
technicalHint: "Required field not provided"
|
|
456
|
-
},
|
|
457
|
-
invalid_field: {
|
|
458
|
-
message: "Some information is invalid",
|
|
459
|
-
action: "Please check your input and try again.",
|
|
460
|
-
technicalHint: "Field validation failed"
|
|
461
|
-
},
|
|
462
|
-
invalid_amount: {
|
|
463
|
-
message: "Payment amount is invalid",
|
|
464
|
-
action: "Please check the amount and try again.",
|
|
465
|
-
technicalHint: "Amount validation failed"
|
|
466
|
-
},
|
|
467
|
-
invalid_wallet: {
|
|
468
|
-
message: "Wallet address is invalid",
|
|
469
|
-
action: "Please reconnect your wallet and try again.",
|
|
470
|
-
technicalHint: "Wallet address validation failed"
|
|
471
|
-
},
|
|
472
|
-
invalid_resource: {
|
|
473
|
-
message: "Invalid item selection",
|
|
474
|
-
action: "Please refresh the page and try again.",
|
|
475
|
-
technicalHint: "Resource ID validation failed"
|
|
476
|
-
},
|
|
477
|
-
invalid_coupon: {
|
|
478
|
-
message: "Invalid coupon code",
|
|
479
|
-
action: "Please check the coupon code and try again.",
|
|
480
|
-
technicalHint: "Coupon code format invalid"
|
|
481
|
-
},
|
|
482
|
-
invalid_cart_item: {
|
|
483
|
-
message: "One or more cart items are invalid",
|
|
484
|
-
action: "Please review your cart and try again.",
|
|
485
|
-
technicalHint: "Cart item validation failed"
|
|
486
|
-
},
|
|
487
|
-
empty_cart: {
|
|
488
|
-
message: "Your cart is empty",
|
|
489
|
-
action: "Please add items to your cart before checking out.",
|
|
490
|
-
technicalHint: "Cart contains no items"
|
|
491
|
-
},
|
|
492
|
-
// ===== RESOURCE/STATE ERRORS (404) =====
|
|
493
|
-
resource_not_found: {
|
|
494
|
-
message: "Item not found",
|
|
495
|
-
action: "This item may no longer be available. Please refresh and try again.",
|
|
496
|
-
technicalHint: "Resource not found in database"
|
|
497
|
-
},
|
|
498
|
-
cart_not_found: {
|
|
499
|
-
message: "Shopping cart not found",
|
|
500
|
-
action: "Your cart may have expired. Please start a new order.",
|
|
501
|
-
technicalHint: "Cart ID not found"
|
|
502
|
-
},
|
|
503
|
-
refund_not_found: {
|
|
504
|
-
message: "Refund not found",
|
|
505
|
-
action: "Please check your refund reference number or contact support.",
|
|
506
|
-
technicalHint: "Refund ID not found"
|
|
507
|
-
},
|
|
508
|
-
product_not_found: {
|
|
509
|
-
message: "Product not available",
|
|
510
|
-
action: "This product may no longer be available. Please browse our current selection.",
|
|
511
|
-
technicalHint: "Product ID not found"
|
|
512
|
-
},
|
|
513
|
-
coupon_not_found: {
|
|
514
|
-
message: "Coupon code not found",
|
|
515
|
-
action: "Please check the coupon code or remove it to continue.",
|
|
516
|
-
technicalHint: "Coupon code not in database"
|
|
517
|
-
},
|
|
518
|
-
session_not_found: {
|
|
519
|
-
message: "Payment session expired",
|
|
520
|
-
action: "Please start a new payment.",
|
|
521
|
-
technicalHint: "Session ID not found or expired"
|
|
522
|
-
},
|
|
523
|
-
cart_already_paid: {
|
|
524
|
-
message: "This order has already been paid",
|
|
525
|
-
action: "Check your order history. If you need to make another purchase, please start a new order.",
|
|
526
|
-
technicalHint: "Cart marked as paid"
|
|
527
|
-
},
|
|
528
|
-
refund_already_processed: {
|
|
529
|
-
message: "This refund has already been processed",
|
|
530
|
-
action: "Check your transaction history or contact support for details.",
|
|
531
|
-
technicalHint: "Refund already completed"
|
|
532
|
-
},
|
|
533
|
-
// ===== COUPON-SPECIFIC ERRORS (409) =====
|
|
534
|
-
coupon_expired: {
|
|
535
|
-
message: "Coupon has expired",
|
|
536
|
-
action: "Please remove the coupon code or use a different code.",
|
|
537
|
-
technicalHint: "Coupon expiration date passed"
|
|
538
|
-
},
|
|
539
|
-
coupon_usage_limit_reached: {
|
|
540
|
-
message: "Coupon usage limit reached",
|
|
541
|
-
action: "This coupon has been fully redeemed. Please try a different code.",
|
|
542
|
-
technicalHint: "Coupon max uses exceeded"
|
|
543
|
-
},
|
|
544
|
-
coupon_not_applicable: {
|
|
545
|
-
message: "Coupon cannot be applied to this purchase",
|
|
546
|
-
action: "Please check the coupon terms or remove it to continue.",
|
|
547
|
-
technicalHint: "Coupon conditions not met"
|
|
548
|
-
},
|
|
549
|
-
coupon_wrong_payment_method: {
|
|
550
|
-
message: "Coupon not valid for this payment method",
|
|
551
|
-
action: "Try a different payment method or remove the coupon code.",
|
|
552
|
-
technicalHint: "Coupon restricted to specific payment methods"
|
|
553
|
-
},
|
|
554
|
-
// ===== EXTERNAL SERVICE ERRORS (502) =====
|
|
555
|
-
stripe_error: {
|
|
556
|
-
message: "Card payment service temporarily unavailable",
|
|
557
|
-
action: "Please try again in a moment, or use cryptocurrency payment instead.",
|
|
558
|
-
technicalHint: "Stripe API error"
|
|
559
|
-
},
|
|
560
|
-
rpc_error: {
|
|
561
|
-
message: "Blockchain network temporarily unavailable",
|
|
562
|
-
action: "Please try again in a moment, or use card payment instead.",
|
|
563
|
-
technicalHint: "Solana RPC error"
|
|
564
|
-
},
|
|
565
|
-
network_error: {
|
|
566
|
-
message: "Network connection issue",
|
|
567
|
-
action: "Please check your internet connection and try again.",
|
|
568
|
-
technicalHint: "Network request failed"
|
|
569
|
-
},
|
|
570
|
-
// ===== INTERNAL/SYSTEM ERRORS (500) =====
|
|
571
|
-
internal_error: {
|
|
572
|
-
message: "Something went wrong on our end",
|
|
573
|
-
action: "Please try again. If this continues, contact support.",
|
|
574
|
-
technicalHint: "Internal server error"
|
|
575
|
-
},
|
|
576
|
-
database_error: {
|
|
577
|
-
message: "Service temporarily unavailable",
|
|
578
|
-
action: "Please try again in a moment.",
|
|
579
|
-
technicalHint: "Database operation failed"
|
|
580
|
-
},
|
|
581
|
-
config_error: {
|
|
582
|
-
message: "Service configuration error",
|
|
583
|
-
action: "Please contact support for assistance.",
|
|
584
|
-
technicalHint: "Server misconfiguration"
|
|
585
|
-
}
|
|
586
|
-
};
|
|
587
|
-
function it(t) {
|
|
588
|
-
return nt[t] || {
|
|
589
|
-
message: "An unexpected error occurred",
|
|
590
|
-
action: "Please try again or contact support if this continues.",
|
|
591
|
-
technicalHint: `Unknown error code: ${t}`
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
class N extends Error {
|
|
595
|
-
/** Machine-readable error code enum */
|
|
596
|
-
code;
|
|
597
|
-
/** Whether this error can be safely retried */
|
|
598
|
-
retryable;
|
|
599
|
-
/** Additional error context */
|
|
600
|
-
details;
|
|
601
|
-
/** HTTP status code (if from API response) */
|
|
602
|
-
httpStatus;
|
|
603
|
-
constructor(e, r, a = !1, n, i) {
|
|
604
|
-
super(r), this.name = "PaymentError", this.code = e, this.retryable = a, this.details = n, this.httpStatus = i, Object.setPrototypeOf(this, N.prototype);
|
|
605
|
-
}
|
|
606
|
-
/**
|
|
607
|
-
* Check if this error is retryable
|
|
608
|
-
*/
|
|
609
|
-
canRetry() {
|
|
610
|
-
return this.retryable;
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* Check if this is a specific error code
|
|
614
|
-
*/
|
|
615
|
-
is(e) {
|
|
616
|
-
return this.code === e;
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* Check if this error is in a specific category
|
|
620
|
-
*/
|
|
621
|
-
isInCategory(e) {
|
|
622
|
-
return e.includes(this.code);
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Get a user-friendly error message
|
|
626
|
-
* Uses structured error messages with actionable guidance
|
|
627
|
-
*/
|
|
628
|
-
getUserMessage() {
|
|
629
|
-
const e = this.getErrorInfo();
|
|
630
|
-
return e.action ? `${e.message} ${e.action}` : e.message;
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* Get short error message without action guidance
|
|
634
|
-
*/
|
|
635
|
-
getShortMessage() {
|
|
636
|
-
return this.getErrorInfo().message;
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* Get actionable guidance for this error
|
|
640
|
-
*/
|
|
641
|
-
getAction() {
|
|
642
|
-
return this.getErrorInfo().action;
|
|
643
|
-
}
|
|
644
|
-
/**
|
|
645
|
-
* Get error info from error messages map
|
|
646
|
-
* @private
|
|
647
|
-
*/
|
|
648
|
-
getErrorInfo() {
|
|
649
|
-
return it(this.code);
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Create PaymentError from API error response
|
|
653
|
-
*
|
|
654
|
-
* If `retryable` field is not present (Rust server), infers retryability
|
|
655
|
-
* from error codes using ERROR_CATEGORIES.RETRYABLE.
|
|
656
|
-
*/
|
|
657
|
-
static fromErrorResponse(e, r) {
|
|
658
|
-
const a = e.error.retryable ?? ot.RETRYABLE.includes(e.error.code);
|
|
659
|
-
return new N(
|
|
660
|
-
e.error.code,
|
|
661
|
-
e.error.message,
|
|
662
|
-
a,
|
|
663
|
-
e.error.details,
|
|
664
|
-
r
|
|
665
|
-
);
|
|
666
|
-
}
|
|
667
|
-
/**
|
|
668
|
-
* Create PaymentError from unknown error
|
|
669
|
-
* Useful for catch blocks where error type is unknown
|
|
670
|
-
*/
|
|
671
|
-
static fromUnknown(e) {
|
|
672
|
-
return e instanceof N ? e : e instanceof Error ? new N(
|
|
673
|
-
"internal_error",
|
|
674
|
-
e.message,
|
|
675
|
-
!1
|
|
676
|
-
) : new N(
|
|
677
|
-
"internal_error",
|
|
678
|
-
String(e),
|
|
679
|
-
!1
|
|
680
|
-
);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
const ot = {
|
|
684
|
-
/** Insufficient funds errors requiring user to add funds */
|
|
685
|
-
INSUFFICIENT_FUNDS: [
|
|
686
|
-
"insufficient_funds_sol",
|
|
687
|
-
"insufficient_funds_token"
|
|
688
|
-
/* INSUFFICIENT_FUNDS_TOKEN */
|
|
689
|
-
],
|
|
690
|
-
/** Transaction state errors that may resolve with time */
|
|
691
|
-
TRANSACTION_PENDING: [
|
|
692
|
-
"transaction_not_confirmed",
|
|
693
|
-
"transaction_not_found"
|
|
694
|
-
/* TRANSACTION_NOT_FOUND */
|
|
695
|
-
],
|
|
696
|
-
/** Validation errors requiring input correction */
|
|
697
|
-
VALIDATION: [
|
|
698
|
-
"missing_field",
|
|
699
|
-
"invalid_field",
|
|
700
|
-
"invalid_amount",
|
|
701
|
-
"invalid_wallet",
|
|
702
|
-
"invalid_resource",
|
|
703
|
-
"invalid_cart_item",
|
|
704
|
-
"empty_cart"
|
|
705
|
-
/* EMPTY_CART */
|
|
706
|
-
],
|
|
707
|
-
/** Coupon-related errors */
|
|
708
|
-
COUPON: [
|
|
709
|
-
"invalid_coupon",
|
|
710
|
-
"coupon_not_found",
|
|
711
|
-
"coupon_expired",
|
|
712
|
-
"coupon_usage_limit_reached",
|
|
713
|
-
"coupon_not_applicable",
|
|
714
|
-
"coupon_wrong_payment_method"
|
|
715
|
-
/* COUPON_WRONG_PAYMENT_METHOD */
|
|
716
|
-
],
|
|
717
|
-
/** Retryable errors (temporary failures) */
|
|
718
|
-
RETRYABLE: [
|
|
719
|
-
"transaction_not_confirmed",
|
|
720
|
-
"rpc_error",
|
|
721
|
-
"network_error",
|
|
722
|
-
"stripe_error"
|
|
723
|
-
/* STRIPE_ERROR */
|
|
724
|
-
],
|
|
725
|
-
/** Resource not found errors */
|
|
726
|
-
NOT_FOUND: [
|
|
727
|
-
"resource_not_found",
|
|
728
|
-
"cart_not_found",
|
|
729
|
-
"refund_not_found",
|
|
730
|
-
"product_not_found",
|
|
731
|
-
"coupon_not_found",
|
|
732
|
-
"session_not_found",
|
|
733
|
-
"credits_hold_not_found"
|
|
734
|
-
/* CREDITS_HOLD_NOT_FOUND */
|
|
735
|
-
],
|
|
736
|
-
/** Credits-related errors */
|
|
737
|
-
CREDITS: [
|
|
738
|
-
"insufficient_credits",
|
|
739
|
-
"credits_hold_expired",
|
|
740
|
-
"credits_hold_not_found"
|
|
741
|
-
/* CREDITS_HOLD_NOT_FOUND */
|
|
742
|
-
],
|
|
743
|
-
/** Security/rate limit errors */
|
|
744
|
-
SECURITY: [
|
|
745
|
-
"invalid_redirect_url",
|
|
746
|
-
"rate_limit_exceeded",
|
|
747
|
-
"nonce_already_used"
|
|
748
|
-
/* NONCE_ALREADY_USED */
|
|
749
|
-
]
|
|
750
|
-
}, fe = 300 * 1e3, G = /* @__PURE__ */ new Map();
|
|
751
|
-
function st(t) {
|
|
752
|
-
if (!t)
|
|
753
|
-
return;
|
|
754
|
-
const e = Number(t);
|
|
755
|
-
if (Number.isFinite(e) && e >= 0)
|
|
756
|
-
return Math.min(e * 1e3, fe);
|
|
757
|
-
const r = Date.parse(t);
|
|
758
|
-
if (!Number.isNaN(r))
|
|
759
|
-
return Math.min(Math.max(r - Date.now(), 0), fe);
|
|
760
|
-
}
|
|
761
|
-
class T extends Error {
|
|
762
|
-
httpStatus;
|
|
763
|
-
retryAfterMs;
|
|
764
|
-
constructor(e, r, a) {
|
|
765
|
-
super(e), this.name = "RetryableHttpError", this.httpStatus = r, this.retryAfterMs = a, Object.setPrototypeOf(this, T.prototype);
|
|
766
|
-
}
|
|
767
|
-
static fromResponse(e, r) {
|
|
768
|
-
const a = e.headers && typeof e.headers.get == "function" ? e.headers.get("Retry-After") : null;
|
|
769
|
-
return new T(
|
|
770
|
-
r,
|
|
771
|
-
e.status,
|
|
772
|
-
st(a)
|
|
773
|
-
);
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
function ct(t) {
|
|
777
|
-
if (t instanceof N || t instanceof T)
|
|
778
|
-
return t.httpStatus;
|
|
779
|
-
}
|
|
780
|
-
function lt(t) {
|
|
781
|
-
if (t instanceof T)
|
|
782
|
-
return t.retryAfterMs;
|
|
783
|
-
}
|
|
784
|
-
function ut(t, e) {
|
|
785
|
-
const r = ct(t);
|
|
786
|
-
if (r != null) {
|
|
787
|
-
const n = r;
|
|
788
|
-
return n === 429 || n >= 500 && n < 600;
|
|
789
|
-
}
|
|
790
|
-
const a = t.message.toLowerCase();
|
|
791
|
-
return !!(a.includes("network") || a.includes("timeout") || a.includes("fetch failed") || a.includes("econnrefused"));
|
|
792
|
-
}
|
|
793
|
-
function dt(t, e, r, a, n) {
|
|
794
|
-
const i = e * Math.pow(r, t), o = Math.min(i, a);
|
|
795
|
-
return Math.floor(n ? o * 0.5 + Math.random() * o * 0.5 : o);
|
|
796
|
-
}
|
|
797
|
-
function ft(t) {
|
|
798
|
-
return new Promise((e) => setTimeout(e, t));
|
|
799
|
-
}
|
|
800
|
-
async function E(t, e = {}) {
|
|
801
|
-
const {
|
|
802
|
-
maxRetries: r = 3,
|
|
803
|
-
initialDelayMs: a = 1e3,
|
|
804
|
-
backoffFactor: n = 2,
|
|
805
|
-
maxDelayMs: i = 3e4,
|
|
806
|
-
jitter: o = !0,
|
|
807
|
-
shouldRetry: s = ut,
|
|
808
|
-
name: c = "retry",
|
|
809
|
-
inFlightKey: u
|
|
810
|
-
} = e, f = async () => {
|
|
811
|
-
let d = null, m = 0;
|
|
812
|
-
for (let A = 0; A <= r; A++)
|
|
813
|
-
try {
|
|
814
|
-
const b = await t();
|
|
815
|
-
return A > 0 && l().debug(
|
|
816
|
-
`[Retry:${c}] Succeeded on attempt ${A + 1}/${r + 1} after ${m}ms`
|
|
817
|
-
), b;
|
|
818
|
-
} catch (b) {
|
|
819
|
-
d = b instanceof Error ? b : new Error(String(b));
|
|
820
|
-
const x = A === r, D = s(d, A);
|
|
821
|
-
if (x || !D)
|
|
822
|
-
throw l().warn(
|
|
823
|
-
`[Retry:${c}] Failed on attempt ${A + 1}/${r + 1}. ${x ? "No more retries." : "Error not retryable."}`
|
|
824
|
-
), d;
|
|
825
|
-
const S = lt(d) ?? dt(
|
|
826
|
-
A,
|
|
827
|
-
a,
|
|
828
|
-
n,
|
|
829
|
-
i,
|
|
830
|
-
o
|
|
831
|
-
);
|
|
832
|
-
m += S, l().warn(
|
|
833
|
-
`[Retry:${c}] Attempt ${A + 1}/${r + 1} failed: ${d.message}. Retrying in ${S}ms...`
|
|
834
|
-
), await ft(S);
|
|
835
|
-
}
|
|
836
|
-
throw d || new Error("Retry failed with no error");
|
|
837
|
-
};
|
|
838
|
-
if (!u)
|
|
839
|
-
return f();
|
|
840
|
-
const h = G.get(u);
|
|
841
|
-
if (h)
|
|
842
|
-
return h;
|
|
843
|
-
const y = f().finally(() => {
|
|
844
|
-
G.get(u) === y && G.delete(u);
|
|
845
|
-
});
|
|
846
|
-
return G.set(u, y), y;
|
|
847
|
-
}
|
|
848
|
-
const v = {
|
|
849
|
-
/** Quick retries for transient errors (3 retries, 1s initial, 2x backoff) */
|
|
850
|
-
QUICK: {
|
|
851
|
-
maxRetries: 3,
|
|
852
|
-
initialDelayMs: 1e3,
|
|
853
|
-
backoffFactor: 2,
|
|
854
|
-
maxDelayMs: 1e4
|
|
855
|
-
},
|
|
856
|
-
/** Standard retries (3 retries, 2s initial, 2x backoff) */
|
|
857
|
-
STANDARD: {
|
|
858
|
-
maxRetries: 3,
|
|
859
|
-
initialDelayMs: 2e3,
|
|
860
|
-
backoffFactor: 2,
|
|
861
|
-
maxDelayMs: 3e4
|
|
862
|
-
},
|
|
863
|
-
/** Aggressive retries for critical operations (5 retries, 500ms initial) */
|
|
864
|
-
AGGRESSIVE: {
|
|
865
|
-
maxRetries: 5,
|
|
866
|
-
initialDelayMs: 500,
|
|
867
|
-
backoffFactor: 1.5,
|
|
868
|
-
maxDelayMs: 15e3
|
|
869
|
-
},
|
|
870
|
-
/** Patient retries for slow backends (5 retries, 5s initial) */
|
|
871
|
-
PATIENT: {
|
|
872
|
-
maxRetries: 5,
|
|
873
|
-
initialDelayMs: 5e3,
|
|
874
|
-
backoffFactor: 2,
|
|
875
|
-
maxDelayMs: 6e4
|
|
876
|
-
},
|
|
877
|
-
/** At most one retry for writes with a real idempotency guarantee */
|
|
878
|
-
IDEMPOTENT_WRITE: {
|
|
879
|
-
maxRetries: 1,
|
|
880
|
-
initialDelayMs: 1e3,
|
|
881
|
-
backoffFactor: 2,
|
|
882
|
-
maxDelayMs: 1e4
|
|
883
|
-
},
|
|
884
|
-
/** Never automatically retry non-idempotent writes */
|
|
885
|
-
WRITE_ONCE: {
|
|
886
|
-
maxRetries: 0,
|
|
887
|
-
initialDelayMs: 1e3,
|
|
888
|
-
backoffFactor: 2,
|
|
889
|
-
maxDelayMs: 1e4
|
|
890
|
-
}
|
|
891
|
-
};
|
|
892
|
-
class ht {
|
|
893
|
-
stripe = null;
|
|
894
|
-
initPromise = null;
|
|
895
|
-
publicKey;
|
|
896
|
-
routeDiscovery;
|
|
897
|
-
complianceCheckEnabled;
|
|
898
|
-
rateLimiter = I(B.PAYMENT);
|
|
899
|
-
circuitBreaker = Q({
|
|
900
|
-
failureThreshold: 5,
|
|
901
|
-
timeout: 1e4,
|
|
902
|
-
// 10 seconds for faster recovery in payment flows
|
|
903
|
-
name: "stripe-manager"
|
|
904
|
-
});
|
|
905
|
-
constructor(e, r, a = !1) {
|
|
906
|
-
this.publicKey = e, this.routeDiscovery = r, this.complianceCheckEnabled = a;
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* Initialize Stripe.js library
|
|
910
|
-
*
|
|
911
|
-
* Concurrent callers share a single loadStripe() call via a cached promise.
|
|
912
|
-
*/
|
|
913
|
-
async initialize() {
|
|
914
|
-
this.stripe || (this.initPromise || (this.initPromise = (async () => {
|
|
915
|
-
try {
|
|
916
|
-
if (this.stripe = await Te(this.publicKey), !this.stripe) throw new Error("Failed to initialize Stripe");
|
|
917
|
-
} catch (e) {
|
|
918
|
-
throw this.initPromise = null, e;
|
|
919
|
-
}
|
|
920
|
-
})()), await this.initPromise);
|
|
921
|
-
}
|
|
922
|
-
/**
|
|
923
|
-
* Create a Stripe checkout session
|
|
924
|
-
*/
|
|
925
|
-
async createSession(e) {
|
|
926
|
-
if (!this.rateLimiter.tryConsume())
|
|
927
|
-
throw new Error("Rate limit exceeded for Stripe session creation. Please try again later.");
|
|
928
|
-
const r = k(), a = JSON.stringify(e);
|
|
929
|
-
try {
|
|
930
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
931
|
-
async () => {
|
|
932
|
-
const n = await this.routeDiscovery.buildUrl("/paywall/v1/stripe-session");
|
|
933
|
-
l().debug("[StripeManager] Creating session", {
|
|
934
|
-
resource: e.resource,
|
|
935
|
-
hasCouponCode: !!e.couponCode,
|
|
936
|
-
hasMetadata: !!(e.metadata && Object.keys(e.metadata).length),
|
|
937
|
-
metadataKeyCount: e.metadata ? Object.keys(e.metadata).length : 0
|
|
938
|
-
});
|
|
939
|
-
const i = await p(n, {
|
|
940
|
-
method: "POST",
|
|
941
|
-
headers: {
|
|
942
|
-
"Content-Type": "application/json",
|
|
943
|
-
"Idempotency-Key": r
|
|
944
|
-
},
|
|
945
|
-
body: a
|
|
946
|
-
});
|
|
947
|
-
if (!i.ok) {
|
|
948
|
-
const o = await w(i, "Failed to create Stripe session");
|
|
949
|
-
throw T.fromResponse(i, o);
|
|
950
|
-
}
|
|
951
|
-
return await i.json();
|
|
952
|
-
},
|
|
953
|
-
{
|
|
954
|
-
...v.IDEMPOTENT_WRITE,
|
|
955
|
-
name: "stripe-create-session",
|
|
956
|
-
inFlightKey: `stripe:create-session:${a}`
|
|
957
|
-
}
|
|
958
|
-
));
|
|
959
|
-
} catch (n) {
|
|
960
|
-
throw n instanceof g ? (l().error("[StripeManager] Circuit breaker is OPEN - Stripe service unavailable"), new Error("Stripe payment service is temporarily unavailable. Please try again in a few moments.")) : n;
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
/**
|
|
964
|
-
* Redirect to Stripe checkout
|
|
965
|
-
*/
|
|
966
|
-
async redirectToCheckout(e) {
|
|
967
|
-
if (this.stripe || await this.initialize(), !this.stripe)
|
|
968
|
-
return {
|
|
969
|
-
success: !1,
|
|
970
|
-
error: "Stripe not initialized"
|
|
971
|
-
};
|
|
972
|
-
const r = await this.stripe.redirectToCheckout({ sessionId: e });
|
|
973
|
-
return r.error ? {
|
|
974
|
-
success: !1,
|
|
975
|
-
error: r.error.message
|
|
976
|
-
} : { success: !0 };
|
|
977
|
-
}
|
|
978
|
-
/**
|
|
979
|
-
* Run a pre-flight compliance check for the given resources.
|
|
980
|
-
* Returns null if cleared, or a PaymentResult with the block reasons.
|
|
981
|
-
*/
|
|
982
|
-
async runComplianceCheck(e) {
|
|
983
|
-
if (!this.complianceCheckEnabled) return null;
|
|
984
|
-
try {
|
|
985
|
-
const r = await this.routeDiscovery.buildUrl("/paywall/v1/compliance-check"), a = await p(r, {
|
|
986
|
-
method: "POST",
|
|
987
|
-
headers: { "Content-Type": "application/json" },
|
|
988
|
-
body: JSON.stringify({ resources: e })
|
|
989
|
-
});
|
|
990
|
-
if (!a.ok) return null;
|
|
991
|
-
const n = await a.json();
|
|
992
|
-
if (!n.cleared)
|
|
993
|
-
return { success: !1, error: `Purchase blocked: ${(n.reasons ?? ["Purchase blocked by compliance check"]).join("; ")}` };
|
|
994
|
-
} catch {
|
|
995
|
-
l().warn("[StripeManager] Compliance pre-check failed, proceeding");
|
|
996
|
-
}
|
|
997
|
-
return null;
|
|
998
|
-
}
|
|
999
|
-
/**
|
|
1000
|
-
* Handle complete payment flow: create session and redirect
|
|
1001
|
-
*/
|
|
1002
|
-
async processPayment(e) {
|
|
1003
|
-
try {
|
|
1004
|
-
const r = await this.runComplianceCheck([e.resource]);
|
|
1005
|
-
if (r) return r;
|
|
1006
|
-
const a = await this.createSession(e);
|
|
1007
|
-
return await this.redirectToCheckout(a.sessionId);
|
|
1008
|
-
} catch (r) {
|
|
1009
|
-
return {
|
|
1010
|
-
success: !1,
|
|
1011
|
-
error: O(r, "Unknown error")
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
/**
|
|
1016
|
-
* Create a Stripe cart checkout session for multiple items
|
|
1017
|
-
*/
|
|
1018
|
-
async processCartCheckout(e) {
|
|
1019
|
-
const {
|
|
1020
|
-
items: r,
|
|
1021
|
-
successUrl: a,
|
|
1022
|
-
cancelUrl: n,
|
|
1023
|
-
metadata: i,
|
|
1024
|
-
customerEmail: o,
|
|
1025
|
-
customerName: s,
|
|
1026
|
-
customerPhone: c,
|
|
1027
|
-
shippingAddress: u,
|
|
1028
|
-
billingAddress: f,
|
|
1029
|
-
couponCode: h,
|
|
1030
|
-
tipAmount: y,
|
|
1031
|
-
shippingMethodId: d,
|
|
1032
|
-
paymentMethodId: m
|
|
1033
|
-
} = e, A = r.map((S) => S.resource), b = await this.runComplianceCheck(A);
|
|
1034
|
-
if (b) return b;
|
|
1035
|
-
if (!this.rateLimiter.tryConsume())
|
|
1036
|
-
return {
|
|
1037
|
-
success: !1,
|
|
1038
|
-
error: "Rate limit exceeded for cart checkout. Please try again later."
|
|
1039
|
-
};
|
|
1040
|
-
const x = k(), M = JSON.stringify({
|
|
1041
|
-
items: r,
|
|
1042
|
-
successUrl: a,
|
|
1043
|
-
cancelUrl: n,
|
|
1044
|
-
metadata: i,
|
|
1045
|
-
customerEmail: o,
|
|
1046
|
-
customerName: s,
|
|
1047
|
-
customerPhone: c,
|
|
1048
|
-
shippingAddress: u,
|
|
1049
|
-
billingAddress: f,
|
|
1050
|
-
coupon: h,
|
|
1051
|
-
couponCode: h,
|
|
1052
|
-
tipAmount: y,
|
|
1053
|
-
shippingMethodId: d,
|
|
1054
|
-
paymentMethodId: m
|
|
1055
|
-
});
|
|
1056
|
-
try {
|
|
1057
|
-
const S = await this.circuitBreaker.execute(async () => await E(
|
|
1058
|
-
async () => {
|
|
1059
|
-
const _ = await this.routeDiscovery.buildUrl("/paywall/v1/cart/checkout"), R = await p(_, {
|
|
1060
|
-
method: "POST",
|
|
1061
|
-
headers: {
|
|
1062
|
-
"Content-Type": "application/json",
|
|
1063
|
-
"Idempotency-Key": x
|
|
1064
|
-
},
|
|
1065
|
-
body: M
|
|
1066
|
-
});
|
|
1067
|
-
if (!R.ok) {
|
|
1068
|
-
const C = await w(R, "Failed to create cart checkout session");
|
|
1069
|
-
throw T.fromResponse(R, C);
|
|
1070
|
-
}
|
|
1071
|
-
return await R.json();
|
|
1072
|
-
},
|
|
1073
|
-
{
|
|
1074
|
-
...v.IDEMPOTENT_WRITE,
|
|
1075
|
-
name: "stripe-cart-checkout",
|
|
1076
|
-
inFlightKey: `stripe:cart-checkout:${M}`
|
|
1077
|
-
}
|
|
1078
|
-
));
|
|
1079
|
-
return await this.redirectToCheckout(S.sessionId);
|
|
1080
|
-
} catch (S) {
|
|
1081
|
-
return S instanceof g ? {
|
|
1082
|
-
success: !1,
|
|
1083
|
-
error: "Stripe payment service is temporarily unavailable. Please try again in a few moments."
|
|
1084
|
-
} : {
|
|
1085
|
-
success: !1,
|
|
1086
|
-
error: O(S, "Cart checkout failed")
|
|
1087
|
-
};
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
const ke = "3.7.8", mt = ke, L = typeof Buffer == "function", he = typeof TextDecoder == "function" ? new TextDecoder() : void 0, me = typeof TextEncoder == "function" ? new TextEncoder() : void 0, yt = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", z = Array.prototype.slice.call(yt), V = ((t) => {
|
|
1092
|
-
let e = {};
|
|
1093
|
-
return t.forEach((r, a) => e[r] = a), e;
|
|
1094
|
-
})(z), pt = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/, P = String.fromCharCode.bind(String), ye = typeof Uint8Array.from == "function" ? Uint8Array.from.bind(Uint8Array) : (t) => new Uint8Array(Array.prototype.slice.call(t, 0)), Re = (t) => t.replace(/=/g, "").replace(/[+\/]/g, (e) => e == "+" ? "-" : "_"), Me = (t) => t.replace(/[^A-Za-z0-9\+\/]/g, ""), De = (t) => {
|
|
1095
|
-
let e, r, a, n, i = "";
|
|
1096
|
-
const o = t.length % 3;
|
|
1097
|
-
for (let s = 0; s < t.length; ) {
|
|
1098
|
-
if ((r = t.charCodeAt(s++)) > 255 || (a = t.charCodeAt(s++)) > 255 || (n = t.charCodeAt(s++)) > 255)
|
|
1099
|
-
throw new TypeError("invalid character found");
|
|
1100
|
-
e = r << 16 | a << 8 | n, i += z[e >> 18 & 63] + z[e >> 12 & 63] + z[e >> 6 & 63] + z[e & 63];
|
|
1101
|
-
}
|
|
1102
|
-
return o ? i.slice(0, o - 3) + "===".substring(o) : i;
|
|
1103
|
-
}, ce = typeof btoa == "function" ? (t) => btoa(t) : L ? (t) => Buffer.from(t, "binary").toString("base64") : De, ne = L ? (t) => Buffer.from(t).toString("base64") : (t) => {
|
|
1104
|
-
let r = [];
|
|
1105
|
-
for (let a = 0, n = t.length; a < n; a += 4096)
|
|
1106
|
-
r.push(P.apply(null, t.subarray(a, a + 4096)));
|
|
1107
|
-
return ce(r.join(""));
|
|
1108
|
-
}, $ = (t, e = !1) => e ? Re(ne(t)) : ne(t), At = (t) => {
|
|
1109
|
-
if (t.length < 2) {
|
|
1110
|
-
var e = t.charCodeAt(0);
|
|
1111
|
-
return e < 128 ? t : e < 2048 ? P(192 | e >>> 6) + P(128 | e & 63) : P(224 | e >>> 12 & 15) + P(128 | e >>> 6 & 63) + P(128 | e & 63);
|
|
1112
|
-
} else {
|
|
1113
|
-
var e = 65536 + (t.charCodeAt(0) - 55296) * 1024 + (t.charCodeAt(1) - 56320);
|
|
1114
|
-
return P(240 | e >>> 18 & 7) + P(128 | e >>> 12 & 63) + P(128 | e >>> 6 & 63) + P(128 | e & 63);
|
|
1115
|
-
}
|
|
1116
|
-
}, gt = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g, Oe = (t) => t.replace(gt, At), pe = L ? (t) => Buffer.from(t, "utf8").toString("base64") : me ? (t) => ne(me.encode(t)) : (t) => ce(Oe(t)), H = (t, e = !1) => e ? Re(pe(t)) : pe(t), Ae = (t) => H(t, !0), wt = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g, bt = (t) => {
|
|
1117
|
-
switch (t.length) {
|
|
1118
|
-
case 4:
|
|
1119
|
-
var e = (7 & t.charCodeAt(0)) << 18 | (63 & t.charCodeAt(1)) << 12 | (63 & t.charCodeAt(2)) << 6 | 63 & t.charCodeAt(3), r = e - 65536;
|
|
1120
|
-
return P((r >>> 10) + 55296) + P((r & 1023) + 56320);
|
|
1121
|
-
case 3:
|
|
1122
|
-
return P((15 & t.charCodeAt(0)) << 12 | (63 & t.charCodeAt(1)) << 6 | 63 & t.charCodeAt(2));
|
|
1123
|
-
default:
|
|
1124
|
-
return P((31 & t.charCodeAt(0)) << 6 | 63 & t.charCodeAt(1));
|
|
1125
|
-
}
|
|
1126
|
-
}, Ie = (t) => t.replace(wt, bt), Be = (t) => {
|
|
1127
|
-
if (t = t.replace(/\s+/g, ""), !pt.test(t))
|
|
1128
|
-
throw new TypeError("malformed base64.");
|
|
1129
|
-
t += "==".slice(2 - (t.length & 3));
|
|
1130
|
-
let e, r, a, n = [];
|
|
1131
|
-
for (let i = 0; i < t.length; )
|
|
1132
|
-
e = V[t.charAt(i++)] << 18 | V[t.charAt(i++)] << 12 | (r = V[t.charAt(i++)]) << 6 | (a = V[t.charAt(i++)]), r === 64 ? n.push(P(e >> 16 & 255)) : a === 64 ? n.push(P(e >> 16 & 255, e >> 8 & 255)) : n.push(P(e >> 16 & 255, e >> 8 & 255, e & 255));
|
|
1133
|
-
return n.join("");
|
|
1134
|
-
}, le = typeof atob == "function" ? (t) => atob(Me(t)) : L ? (t) => Buffer.from(t, "base64").toString("binary") : Be, _e = L ? (t) => ye(Buffer.from(t, "base64")) : (t) => ye(le(t).split("").map((e) => e.charCodeAt(0))), Ne = (t) => _e(Fe(t)), vt = L ? (t) => Buffer.from(t, "base64").toString("utf8") : he ? (t) => he.decode(_e(t)) : (t) => Ie(le(t)), Fe = (t) => Me(t.replace(/[-_]/g, (e) => e == "-" ? "+" : "/")), ie = (t) => vt(Fe(t)), Et = (t) => {
|
|
1135
|
-
if (typeof t != "string")
|
|
1136
|
-
return !1;
|
|
1137
|
-
const e = t.replace(/\s+/g, "").replace(/={0,2}$/, "");
|
|
1138
|
-
return !/[^\s0-9a-zA-Z\+/]/.test(e) || !/[^\s0-9a-zA-Z\-_]/.test(e);
|
|
1139
|
-
}, Ue = (t) => ({
|
|
1140
|
-
value: t,
|
|
1141
|
-
enumerable: !1,
|
|
1142
|
-
writable: !0,
|
|
1143
|
-
configurable: !0
|
|
1144
|
-
}), He = function() {
|
|
1145
|
-
const t = (e, r) => Object.defineProperty(String.prototype, e, Ue(r));
|
|
1146
|
-
t("fromBase64", function() {
|
|
1147
|
-
return ie(this);
|
|
1148
|
-
}), t("toBase64", function(e) {
|
|
1149
|
-
return H(this, e);
|
|
1150
|
-
}), t("toBase64URI", function() {
|
|
1151
|
-
return H(this, !0);
|
|
1152
|
-
}), t("toBase64URL", function() {
|
|
1153
|
-
return H(this, !0);
|
|
1154
|
-
}), t("toUint8Array", function() {
|
|
1155
|
-
return Ne(this);
|
|
1156
|
-
});
|
|
1157
|
-
}, Le = function() {
|
|
1158
|
-
const t = (e, r) => Object.defineProperty(Uint8Array.prototype, e, Ue(r));
|
|
1159
|
-
t("toBase64", function(e) {
|
|
1160
|
-
return $(this, e);
|
|
1161
|
-
}), t("toBase64URI", function() {
|
|
1162
|
-
return $(this, !0);
|
|
1163
|
-
}), t("toBase64URL", function() {
|
|
1164
|
-
return $(this, !0);
|
|
1165
|
-
});
|
|
1166
|
-
}, Ct = () => {
|
|
1167
|
-
He(), Le();
|
|
1168
|
-
}, ge = {
|
|
1169
|
-
version: ke,
|
|
1170
|
-
VERSION: mt,
|
|
1171
|
-
atob: le,
|
|
1172
|
-
atobPolyfill: Be,
|
|
1173
|
-
btoa: ce,
|
|
1174
|
-
btoaPolyfill: De,
|
|
1175
|
-
fromBase64: ie,
|
|
1176
|
-
toBase64: H,
|
|
1177
|
-
encode: H,
|
|
1178
|
-
encodeURI: Ae,
|
|
1179
|
-
encodeURL: Ae,
|
|
1180
|
-
utob: Oe,
|
|
1181
|
-
btou: Ie,
|
|
1182
|
-
decode: ie,
|
|
1183
|
-
isValid: Et,
|
|
1184
|
-
fromUint8Array: $,
|
|
1185
|
-
toUint8Array: Ne,
|
|
1186
|
-
extendString: He,
|
|
1187
|
-
extendUint8Array: Le,
|
|
1188
|
-
extendBuiltins: Ct
|
|
1189
|
-
};
|
|
1190
|
-
class Pt {
|
|
1191
|
-
routeDiscovery;
|
|
1192
|
-
quoteRateLimiter = I(B.QUOTE);
|
|
1193
|
-
verifyRateLimiter = I(B.PAYMENT);
|
|
1194
|
-
circuitBreaker = Q({
|
|
1195
|
-
failureThreshold: 5,
|
|
1196
|
-
timeout: 1e4,
|
|
1197
|
-
// 10 seconds for faster recovery in payment flows
|
|
1198
|
-
name: "x402-manager"
|
|
1199
|
-
});
|
|
1200
|
-
constructor(e) {
|
|
1201
|
-
this.routeDiscovery = e;
|
|
1202
|
-
}
|
|
1203
|
-
/**
|
|
1204
|
-
* Request a protected resource and get x402 requirement
|
|
1205
|
-
* SECURITY: Resource ID and coupon codes sent in request body to prevent leakage
|
|
1206
|
-
* Prevents exposure of product IDs, SKUs, and business-sensitive identifiers in logs
|
|
1207
|
-
*/
|
|
1208
|
-
async requestQuote(e) {
|
|
1209
|
-
const { resource: r, couponCode: a } = e;
|
|
1210
|
-
if (!this.quoteRateLimiter.tryConsume())
|
|
1211
|
-
throw new Error("Rate limit exceeded for quote requests. Please try again later.");
|
|
1212
|
-
try {
|
|
1213
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1214
|
-
async () => {
|
|
1215
|
-
const n = "/paywall/v1/quote";
|
|
1216
|
-
l().debug(
|
|
1217
|
-
"[X402Manager] Requesting quote",
|
|
1218
|
-
a ? "with coupon" : "without coupon"
|
|
1219
|
-
);
|
|
1220
|
-
const i = await this.routeDiscovery.buildUrl(n), o = await p(i, {
|
|
1221
|
-
method: "POST",
|
|
1222
|
-
headers: {
|
|
1223
|
-
"Content-Type": "application/json"
|
|
1224
|
-
},
|
|
1225
|
-
body: JSON.stringify({
|
|
1226
|
-
resource: r,
|
|
1227
|
-
couponCode: a || null
|
|
1228
|
-
})
|
|
1229
|
-
});
|
|
1230
|
-
if (o.status !== 402)
|
|
1231
|
-
throw new Error(`Expected 402 status, got ${o.status}`);
|
|
1232
|
-
const s = await o.json();
|
|
1233
|
-
if (s.crypto) {
|
|
1234
|
-
const c = s.crypto;
|
|
1235
|
-
if (!this.validateRequirement(c))
|
|
1236
|
-
throw new Error("Invalid x402 requirement received from server: missing required fields");
|
|
1237
|
-
return c;
|
|
1238
|
-
} else if (s.accepts && s.accepts.length > 0) {
|
|
1239
|
-
const c = s.accepts[0];
|
|
1240
|
-
if (!this.validateRequirement(c))
|
|
1241
|
-
throw new Error("Invalid x402 requirement received from server: missing required fields");
|
|
1242
|
-
return c;
|
|
1243
|
-
} else
|
|
1244
|
-
throw new Error("Invalid x402 response: missing crypto or accepts field");
|
|
1245
|
-
},
|
|
1246
|
-
{ ...v.QUICK, name: "x402-quote" }
|
|
1247
|
-
));
|
|
1248
|
-
} catch (n) {
|
|
1249
|
-
throw n instanceof g ? (l().error("[X402Manager] Circuit breaker is OPEN - x402 service unavailable"), new Error("Payment service is temporarily unavailable. Please try again in a few moments.")) : n;
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
/**
|
|
1253
|
-
* Request a cart quote for multiple items
|
|
1254
|
-
*/
|
|
1255
|
-
async requestCartQuote(e) {
|
|
1256
|
-
const { items: r, metadata: a, couponCode: n } = e;
|
|
1257
|
-
if (!this.quoteRateLimiter.tryConsume())
|
|
1258
|
-
throw new Error("Rate limit exceeded for cart quote requests. Please try again later.");
|
|
1259
|
-
const i = k();
|
|
1260
|
-
try {
|
|
1261
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1262
|
-
async () => {
|
|
1263
|
-
const o = await this.routeDiscovery.buildUrl("/paywall/v1/cart/quote"), c = await p(o, {
|
|
1264
|
-
method: "POST",
|
|
1265
|
-
headers: {
|
|
1266
|
-
"Content-Type": "application/json",
|
|
1267
|
-
"Idempotency-Key": i
|
|
1268
|
-
},
|
|
1269
|
-
body: JSON.stringify({
|
|
1270
|
-
items: r,
|
|
1271
|
-
metadata: a,
|
|
1272
|
-
coupon: n,
|
|
1273
|
-
// New Rust server field
|
|
1274
|
-
couponCode: n
|
|
1275
|
-
// Legacy Go server field (backwards compat)
|
|
1276
|
-
})
|
|
1277
|
-
});
|
|
1278
|
-
if (c.status !== 402 && !c.ok) {
|
|
1279
|
-
const f = await w(c, "Failed to get cart quote");
|
|
1280
|
-
throw new Error(f);
|
|
1281
|
-
}
|
|
1282
|
-
const u = await c.json();
|
|
1283
|
-
if (!u.cartId || !u.quote)
|
|
1284
|
-
throw new Error("Invalid cart quote response: missing cartId or quote");
|
|
1285
|
-
if (u.quote.crypto && !this.validateRequirement(u.quote.crypto))
|
|
1286
|
-
throw new Error("Invalid x402 cart quote: missing required fields in crypto quote");
|
|
1287
|
-
return u;
|
|
1288
|
-
},
|
|
1289
|
-
{ ...v.QUICK, name: "x402-cart-quote" }
|
|
1290
|
-
));
|
|
1291
|
-
} catch (o) {
|
|
1292
|
-
throw o instanceof g ? (l().error("[X402Manager] Circuit breaker is OPEN - cart quote service unavailable"), new Error("Payment service is temporarily unavailable. Please try again in a few moments.")) : o;
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
/**
|
|
1296
|
-
* Build X-PAYMENT header from payment payload (base64 encoded)
|
|
1297
|
-
*/
|
|
1298
|
-
buildPaymentHeader(e) {
|
|
1299
|
-
const r = JSON.stringify(e);
|
|
1300
|
-
return ge.encode(r);
|
|
1301
|
-
}
|
|
1302
|
-
/**
|
|
1303
|
-
* Parse X-PAYMENT-RESPONSE header (base64 encoded settlement response)
|
|
1304
|
-
*/
|
|
1305
|
-
parseSettlementResponse(e) {
|
|
1306
|
-
const r = e.headers.get("X-PAYMENT-RESPONSE");
|
|
1307
|
-
if (!r)
|
|
1308
|
-
return null;
|
|
1309
|
-
try {
|
|
1310
|
-
const a = ge.decode(r), n = JSON.parse(a);
|
|
1311
|
-
return typeof n.success != "boolean" ? (l().error("Invalid settlement response: missing success field"), null) : n;
|
|
1312
|
-
} catch (a) {
|
|
1313
|
-
return l().error("Failed to parse settlement response:", a), null;
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
/**
|
|
1317
|
-
* Retry request with payment proof
|
|
1318
|
-
* SECURITY: Coupon and metadata sent in X-PAYMENT header payload, NOT query strings
|
|
1319
|
-
*/
|
|
1320
|
-
async submitPayment(e) {
|
|
1321
|
-
const {
|
|
1322
|
-
resource: r,
|
|
1323
|
-
payload: a,
|
|
1324
|
-
couponCode: n,
|
|
1325
|
-
metadata: i,
|
|
1326
|
-
resourceType: o = "regular"
|
|
1327
|
-
} = e;
|
|
1328
|
-
if (!this.verifyRateLimiter.tryConsume())
|
|
1329
|
-
return {
|
|
1330
|
-
success: !1,
|
|
1331
|
-
error: "Rate limit exceeded for payment verification. Please try again later."
|
|
1332
|
-
};
|
|
1333
|
-
const s = k();
|
|
1334
|
-
try {
|
|
1335
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1336
|
-
async () => {
|
|
1337
|
-
const u = {
|
|
1338
|
-
...a,
|
|
1339
|
-
payload: {
|
|
1340
|
-
...a.payload,
|
|
1341
|
-
resource: r,
|
|
1342
|
-
resourceType: o,
|
|
1343
|
-
metadata: {
|
|
1344
|
-
...a.payload.metadata || {},
|
|
1345
|
-
// Preserve existing metadata
|
|
1346
|
-
...i || {},
|
|
1347
|
-
// Layer in new metadata
|
|
1348
|
-
...n ? { couponCode: n } : {}
|
|
1349
|
-
// Add coupon if present
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
}, f = this.buildPaymentHeader(u), h = "/paywall/v1/verify";
|
|
1353
|
-
l().debug("[X402Manager] Submitting payment", {
|
|
1354
|
-
resourceType: o,
|
|
1355
|
-
hasCoupon: !!n,
|
|
1356
|
-
hasMetadata: !!i
|
|
1357
|
-
});
|
|
1358
|
-
const y = await this.routeDiscovery.buildUrl(h), d = await p(y, {
|
|
1359
|
-
method: "POST",
|
|
1360
|
-
headers: {
|
|
1361
|
-
"Content-Type": "application/json",
|
|
1362
|
-
"X-PAYMENT": f,
|
|
1363
|
-
"Idempotency-Key": s
|
|
1364
|
-
}
|
|
1365
|
-
});
|
|
1366
|
-
if (d.ok) {
|
|
1367
|
-
const { settlement: A, transactionId: b } = await this.handlePaymentVerification(
|
|
1368
|
-
d,
|
|
1369
|
-
a.payload.signature
|
|
1370
|
-
);
|
|
1371
|
-
return {
|
|
1372
|
-
success: !0,
|
|
1373
|
-
transactionId: b,
|
|
1374
|
-
settlement: A || void 0
|
|
1375
|
-
};
|
|
1376
|
-
}
|
|
1377
|
-
return {
|
|
1378
|
-
success: !1,
|
|
1379
|
-
error: await w(d, "Payment verification failed", !0)
|
|
1380
|
-
};
|
|
1381
|
-
},
|
|
1382
|
-
{ maxRetries: 0, initialDelayMs: 0, backoffFactor: 1, maxDelayMs: 0, name: "x402-verify" }
|
|
1383
|
-
));
|
|
1384
|
-
} catch (c) {
|
|
1385
|
-
return c instanceof g ? {
|
|
1386
|
-
success: !1,
|
|
1387
|
-
error: "Payment verification service is temporarily unavailable. Please try again in a few moments."
|
|
1388
|
-
} : {
|
|
1389
|
-
success: !1,
|
|
1390
|
-
error: O(c, "Unknown error")
|
|
1391
|
-
};
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
/**
|
|
1395
|
-
* Build a complete gasless transaction on the backend
|
|
1396
|
-
* Returns an unsigned transaction with all instructions (compute budget, transfer, memo)
|
|
1397
|
-
*/
|
|
1398
|
-
async buildGaslessTransaction(e) {
|
|
1399
|
-
const { resourceId: r, userWallet: a, feePayer: n, couponCode: i } = e;
|
|
1400
|
-
if (!this.quoteRateLimiter.tryConsume())
|
|
1401
|
-
throw new Error("Rate limit exceeded for gasless transaction requests. Please try again later.");
|
|
1402
|
-
try {
|
|
1403
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1404
|
-
async () => {
|
|
1405
|
-
const o = await this.routeDiscovery.buildUrl(
|
|
1406
|
-
"/paywall/v1/gasless-transaction"
|
|
1407
|
-
), s = await p(o, {
|
|
1408
|
-
method: "POST",
|
|
1409
|
-
headers: {
|
|
1410
|
-
"Content-Type": "application/json"
|
|
1411
|
-
},
|
|
1412
|
-
body: JSON.stringify({
|
|
1413
|
-
resourceId: r,
|
|
1414
|
-
userWallet: a,
|
|
1415
|
-
feePayer: n,
|
|
1416
|
-
couponCode: i
|
|
1417
|
-
})
|
|
1418
|
-
});
|
|
1419
|
-
if (!s.ok) {
|
|
1420
|
-
const c = await w(s, "Failed to build gasless transaction");
|
|
1421
|
-
throw new Error(c);
|
|
1422
|
-
}
|
|
1423
|
-
return await s.json();
|
|
1424
|
-
},
|
|
1425
|
-
{ ...v.QUICK, name: "x402-gasless-build" }
|
|
1426
|
-
));
|
|
1427
|
-
} catch (o) {
|
|
1428
|
-
throw o instanceof g ? (l().error("[X402Manager] Circuit breaker is OPEN - gasless transaction service unavailable"), new Error("Gasless transaction service is temporarily unavailable. Please try again in a few moments.")) : o;
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
/**
|
|
1432
|
-
* Submit gasless partial transaction for co-signing
|
|
1433
|
-
* Sends the partially-signed transaction in X-Payment header for backend co-signing
|
|
1434
|
-
* SECURITY: Coupon and metadata sent in X-PAYMENT header payload, NOT query strings
|
|
1435
|
-
*/
|
|
1436
|
-
async submitGaslessTransaction(e) {
|
|
1437
|
-
const {
|
|
1438
|
-
resource: r,
|
|
1439
|
-
partialTx: a,
|
|
1440
|
-
couponCode: n,
|
|
1441
|
-
metadata: i,
|
|
1442
|
-
resourceType: o = "regular",
|
|
1443
|
-
requirement: s
|
|
1444
|
-
} = e;
|
|
1445
|
-
if (!this.verifyRateLimiter.tryConsume())
|
|
1446
|
-
return {
|
|
1447
|
-
success: !1,
|
|
1448
|
-
error: "Rate limit exceeded for gasless transaction verification. Please try again later."
|
|
1449
|
-
};
|
|
1450
|
-
const c = k();
|
|
1451
|
-
try {
|
|
1452
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1453
|
-
async () => {
|
|
1454
|
-
const f = {
|
|
1455
|
-
x402Version: 0,
|
|
1456
|
-
scheme: s?.scheme || "solana-spl-transfer",
|
|
1457
|
-
network: s?.network || "mainnet-beta",
|
|
1458
|
-
payload: {
|
|
1459
|
-
signature: "",
|
|
1460
|
-
// Placeholder - backend will finalize after co-signing
|
|
1461
|
-
transaction: a,
|
|
1462
|
-
feePayer: s?.extra?.feePayer || "",
|
|
1463
|
-
resource: r,
|
|
1464
|
-
resourceType: o,
|
|
1465
|
-
metadata: {
|
|
1466
|
-
...i || {},
|
|
1467
|
-
...n ? { couponCode: n } : {}
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
}, h = this.buildPaymentHeader(f), d = await this.routeDiscovery.buildUrl("/paywall/v1/verify"), m = await p(d, {
|
|
1471
|
-
method: "POST",
|
|
1472
|
-
headers: {
|
|
1473
|
-
"Content-Type": "application/json",
|
|
1474
|
-
"X-PAYMENT": h,
|
|
1475
|
-
"Idempotency-Key": c
|
|
1476
|
-
}
|
|
1477
|
-
});
|
|
1478
|
-
if (m.ok) {
|
|
1479
|
-
const { settlement: b, transactionId: x } = await this.handlePaymentVerification(
|
|
1480
|
-
m,
|
|
1481
|
-
"gasless-tx"
|
|
1482
|
-
);
|
|
1483
|
-
return {
|
|
1484
|
-
success: !0,
|
|
1485
|
-
transactionId: x,
|
|
1486
|
-
settlement: b || void 0
|
|
1487
|
-
};
|
|
1488
|
-
}
|
|
1489
|
-
return {
|
|
1490
|
-
success: !1,
|
|
1491
|
-
error: await w(m, "Gasless transaction failed", !0)
|
|
1492
|
-
};
|
|
1493
|
-
},
|
|
1494
|
-
{ maxRetries: 0, initialDelayMs: 0, backoffFactor: 1, maxDelayMs: 0, name: "x402-gasless-verify" }
|
|
1495
|
-
));
|
|
1496
|
-
} catch (u) {
|
|
1497
|
-
return u instanceof g ? {
|
|
1498
|
-
success: !1,
|
|
1499
|
-
error: "Gasless transaction verification service is temporarily unavailable. Please try again in a few moments."
|
|
1500
|
-
} : {
|
|
1501
|
-
success: !1,
|
|
1502
|
-
error: O(u, "Unknown error")
|
|
1503
|
-
};
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
/**
|
|
1507
|
-
* Handle payment verification response (shared logic for both submitPayment and submitGaslessTransaction)
|
|
1508
|
-
* Parses settlement header and extracts transaction ID from response body
|
|
1509
|
-
* @param response - HTTP response from payment verification endpoint
|
|
1510
|
-
* @param defaultTxId - Fallback transaction ID if JSON parsing fails
|
|
1511
|
-
* @returns Settlement data and transaction ID
|
|
1512
|
-
*/
|
|
1513
|
-
async handlePaymentVerification(e, r) {
|
|
1514
|
-
const a = this.parseSettlementResponse(e), n = e.headers.get("Content-Type") || "";
|
|
1515
|
-
let i = r;
|
|
1516
|
-
if (n.includes("application/json"))
|
|
1517
|
-
try {
|
|
1518
|
-
i = (await e.json()).signature || r;
|
|
1519
|
-
} catch (o) {
|
|
1520
|
-
l().warn("Failed to parse JSON response body:", o);
|
|
1521
|
-
}
|
|
1522
|
-
return { settlement: a, transactionId: i };
|
|
1523
|
-
}
|
|
1524
|
-
/**
|
|
1525
|
-
* Validate x402 requirement structure
|
|
1526
|
-
*/
|
|
1527
|
-
validateRequirement(e) {
|
|
1528
|
-
return !!(e.scheme && e.network && e.maxAmountRequired && e.resource && e.payTo && e.asset && e.maxTimeoutSeconds > 0);
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
class St {
|
|
1532
|
-
stripe = null;
|
|
1533
|
-
initPromise = null;
|
|
1534
|
-
publicKey;
|
|
1535
|
-
routeDiscovery;
|
|
1536
|
-
// Separate rate limiters for different operation types
|
|
1537
|
-
sessionRateLimiter = I(B.PAYMENT);
|
|
1538
|
-
statusRateLimiter = I(B.QUOTE);
|
|
1539
|
-
circuitBreaker = Q({
|
|
1540
|
-
failureThreshold: 5,
|
|
1541
|
-
timeout: 1e4,
|
|
1542
|
-
// 10 seconds for faster recovery
|
|
1543
|
-
name: "subscription-manager"
|
|
1544
|
-
});
|
|
1545
|
-
constructor(e, r) {
|
|
1546
|
-
this.publicKey = e, this.routeDiscovery = r;
|
|
1547
|
-
}
|
|
1548
|
-
/**
|
|
1549
|
-
* Initialize Stripe.js library
|
|
1550
|
-
*
|
|
1551
|
-
* Concurrent callers share a single loadStripe() call via a cached promise.
|
|
1552
|
-
*/
|
|
1553
|
-
async initialize() {
|
|
1554
|
-
this.stripe || (this.initPromise || (this.initPromise = (async () => {
|
|
1555
|
-
if (this.stripe = await Te(this.publicKey), !this.stripe) throw new Error("Failed to initialize Stripe");
|
|
1556
|
-
})()), await this.initPromise);
|
|
1557
|
-
}
|
|
1558
|
-
/** Internal helper: execute with rate limiting, circuit breaker, and retry */
|
|
1559
|
-
async executeWithResilience(e, r, a, n, i = v.STANDARD) {
|
|
1560
|
-
if (!e.tryConsume())
|
|
1561
|
-
throw new Error("Rate limit exceeded. Please try again later.");
|
|
1562
|
-
try {
|
|
1563
|
-
return await this.circuitBreaker.execute(
|
|
1564
|
-
() => E(r, { ...i, name: a })
|
|
1565
|
-
);
|
|
1566
|
-
} catch (o) {
|
|
1567
|
-
throw o instanceof g ? (l().error(`[SubscriptionManager] Circuit breaker OPEN for ${n}`), new Error("Service temporarily unavailable. Please try again in a few moments.")) : o;
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
/**
|
|
1571
|
-
* Create a Stripe subscription checkout session
|
|
1572
|
-
*/
|
|
1573
|
-
async createSubscriptionSession(e) {
|
|
1574
|
-
if (!this.sessionRateLimiter.tryConsume())
|
|
1575
|
-
throw new Error("Rate limit exceeded for subscription session creation. Please try again later.");
|
|
1576
|
-
const r = k(), a = JSON.stringify(e);
|
|
1577
|
-
try {
|
|
1578
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1579
|
-
async () => {
|
|
1580
|
-
const n = await this.routeDiscovery.buildUrl("/paywall/v1/subscription/stripe-session");
|
|
1581
|
-
l().debug("[SubscriptionManager] Creating subscription session:", {
|
|
1582
|
-
resource: e.resource,
|
|
1583
|
-
interval: e.interval,
|
|
1584
|
-
trialDays: e.trialDays
|
|
1585
|
-
});
|
|
1586
|
-
const i = await p(n, {
|
|
1587
|
-
method: "POST",
|
|
1588
|
-
headers: {
|
|
1589
|
-
"Content-Type": "application/json",
|
|
1590
|
-
"Idempotency-Key": r
|
|
1591
|
-
},
|
|
1592
|
-
body: a
|
|
1593
|
-
});
|
|
1594
|
-
if (!i.ok) {
|
|
1595
|
-
const o = await w(
|
|
1596
|
-
i,
|
|
1597
|
-
"Failed to create subscription session"
|
|
1598
|
-
);
|
|
1599
|
-
throw T.fromResponse(i, o);
|
|
1600
|
-
}
|
|
1601
|
-
return await i.json();
|
|
1602
|
-
},
|
|
1603
|
-
{
|
|
1604
|
-
...v.IDEMPOTENT_WRITE,
|
|
1605
|
-
name: "subscription-create-session",
|
|
1606
|
-
inFlightKey: `subscription:create-session:${a}`
|
|
1607
|
-
}
|
|
1608
|
-
));
|
|
1609
|
-
} catch (n) {
|
|
1610
|
-
throw n instanceof g ? (l().error("[SubscriptionManager] Circuit breaker is OPEN - service unavailable"), new Error(
|
|
1611
|
-
"Subscription service is temporarily unavailable. Please try again in a few moments."
|
|
1612
|
-
)) : n;
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
/**
|
|
1616
|
-
* Redirect to Stripe checkout
|
|
1617
|
-
*/
|
|
1618
|
-
async redirectToCheckout(e) {
|
|
1619
|
-
if (this.stripe || await this.initialize(), !this.stripe)
|
|
1620
|
-
return {
|
|
1621
|
-
success: !1,
|
|
1622
|
-
error: "Stripe not initialized"
|
|
1623
|
-
};
|
|
1624
|
-
const r = await this.stripe.redirectToCheckout({ sessionId: e });
|
|
1625
|
-
return r.error ? {
|
|
1626
|
-
success: !1,
|
|
1627
|
-
error: r.error.message
|
|
1628
|
-
} : { success: !0, transactionId: e };
|
|
1629
|
-
}
|
|
1630
|
-
/**
|
|
1631
|
-
* Complete subscription flow: create session and redirect
|
|
1632
|
-
*/
|
|
1633
|
-
async processSubscription(e) {
|
|
1634
|
-
try {
|
|
1635
|
-
const r = await this.createSubscriptionSession(e);
|
|
1636
|
-
return await this.redirectToCheckout(r.sessionId);
|
|
1637
|
-
} catch (r) {
|
|
1638
|
-
return {
|
|
1639
|
-
success: !1,
|
|
1640
|
-
error: O(r, "Subscription failed")
|
|
1641
|
-
};
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
/**
|
|
1645
|
-
* Check subscription status (for x402 gating)
|
|
1646
|
-
*/
|
|
1647
|
-
async checkSubscriptionStatus(e) {
|
|
1648
|
-
if (!this.statusRateLimiter.tryConsume())
|
|
1649
|
-
throw new Error("Rate limit exceeded for subscription status check. Please try again later.");
|
|
1650
|
-
try {
|
|
1651
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1652
|
-
async () => {
|
|
1653
|
-
const r = new URLSearchParams({
|
|
1654
|
-
resource: e.resource,
|
|
1655
|
-
userId: e.userId
|
|
1656
|
-
}), a = await this.routeDiscovery.buildUrl(
|
|
1657
|
-
`/paywall/v1/subscription/status?${r.toString()}`
|
|
1658
|
-
);
|
|
1659
|
-
l().debug("[SubscriptionManager] Checking subscription status:", e);
|
|
1660
|
-
const n = await p(a, {
|
|
1661
|
-
method: "GET",
|
|
1662
|
-
headers: {
|
|
1663
|
-
"Content-Type": "application/json"
|
|
1664
|
-
}
|
|
1665
|
-
});
|
|
1666
|
-
if (!n.ok) {
|
|
1667
|
-
const i = await w(
|
|
1668
|
-
n,
|
|
1669
|
-
"Failed to check subscription status"
|
|
1670
|
-
);
|
|
1671
|
-
throw new Error(i);
|
|
1672
|
-
}
|
|
1673
|
-
return await n.json();
|
|
1674
|
-
},
|
|
1675
|
-
{ ...v.STANDARD, name: "subscription-status-check" }
|
|
1676
|
-
));
|
|
1677
|
-
} catch (r) {
|
|
1678
|
-
throw r instanceof g ? (l().error("[SubscriptionManager] Circuit breaker is OPEN for status check"), new Error(
|
|
1679
|
-
"Subscription status service is temporarily unavailable. Please try again in a few moments."
|
|
1680
|
-
)) : r;
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
/**
|
|
1684
|
-
* Request a subscription quote for x402 crypto payment
|
|
1685
|
-
*/
|
|
1686
|
-
async requestSubscriptionQuote(e, r, a) {
|
|
1687
|
-
if (!this.statusRateLimiter.tryConsume())
|
|
1688
|
-
throw new Error("Rate limit exceeded for subscription quote. Please try again later.");
|
|
1689
|
-
try {
|
|
1690
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1691
|
-
async () => {
|
|
1692
|
-
const n = await this.routeDiscovery.buildUrl("/paywall/v1/subscription/quote"), i = {
|
|
1693
|
-
resource: e,
|
|
1694
|
-
interval: r,
|
|
1695
|
-
couponCode: a?.couponCode,
|
|
1696
|
-
intervalDays: a?.intervalDays
|
|
1697
|
-
};
|
|
1698
|
-
l().debug("[SubscriptionManager] Requesting subscription quote:", i);
|
|
1699
|
-
const o = await p(n, {
|
|
1700
|
-
method: "POST",
|
|
1701
|
-
headers: {
|
|
1702
|
-
"Content-Type": "application/json"
|
|
1703
|
-
},
|
|
1704
|
-
body: JSON.stringify(i)
|
|
1705
|
-
});
|
|
1706
|
-
if (o.status !== 402 && !o.ok) {
|
|
1707
|
-
const s = await w(
|
|
1708
|
-
o,
|
|
1709
|
-
"Failed to get subscription quote"
|
|
1710
|
-
);
|
|
1711
|
-
throw new Error(s);
|
|
1712
|
-
}
|
|
1713
|
-
return await o.json();
|
|
1714
|
-
},
|
|
1715
|
-
{ ...v.STANDARD, name: "subscription-quote" }
|
|
1716
|
-
));
|
|
1717
|
-
} catch (n) {
|
|
1718
|
-
throw n instanceof g ? (l().error("[SubscriptionManager] Circuit breaker is OPEN for quote"), new Error(
|
|
1719
|
-
"Subscription quote service is temporarily unavailable. Please try again in a few moments."
|
|
1720
|
-
)) : n;
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
/** Activate x402 subscription after payment verification */
|
|
1724
|
-
async activateX402Subscription(e) {
|
|
1725
|
-
const r = JSON.stringify(e);
|
|
1726
|
-
return this.executeWithResilience(
|
|
1727
|
-
this.sessionRateLimiter,
|
|
1728
|
-
async () => {
|
|
1729
|
-
const a = await this.routeDiscovery.buildUrl("/paywall/v1/subscription/x402/activate");
|
|
1730
|
-
l().debug("[SubscriptionManager] Activating x402 subscription:", e);
|
|
1731
|
-
const n = await p(a, {
|
|
1732
|
-
method: "POST",
|
|
1733
|
-
headers: { "Content-Type": "application/json" },
|
|
1734
|
-
body: r
|
|
1735
|
-
});
|
|
1736
|
-
if (!n.ok)
|
|
1737
|
-
throw T.fromResponse(
|
|
1738
|
-
n,
|
|
1739
|
-
await w(n, "Failed to activate")
|
|
1740
|
-
);
|
|
1741
|
-
return await n.json();
|
|
1742
|
-
},
|
|
1743
|
-
"subscription-activate",
|
|
1744
|
-
"activation",
|
|
1745
|
-
{
|
|
1746
|
-
...v.IDEMPOTENT_WRITE,
|
|
1747
|
-
inFlightKey: `subscription:activate:${r}`
|
|
1748
|
-
}
|
|
1749
|
-
);
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
class Tt {
|
|
1753
|
-
routeDiscovery;
|
|
1754
|
-
rateLimiter = I(B.PAYMENT);
|
|
1755
|
-
queryRateLimiter = I(B.QUOTE);
|
|
1756
|
-
circuitBreaker = Q({
|
|
1757
|
-
failureThreshold: 5,
|
|
1758
|
-
timeout: 1e4,
|
|
1759
|
-
name: "subscription-change-manager"
|
|
1760
|
-
});
|
|
1761
|
-
constructor(e) {
|
|
1762
|
-
this.routeDiscovery = e;
|
|
1763
|
-
}
|
|
1764
|
-
/** Internal helper: execute with rate limiting, circuit breaker, and retry */
|
|
1765
|
-
async executeWithResilience(e, r, a, n, i = v.STANDARD) {
|
|
1766
|
-
if (!e.tryConsume())
|
|
1767
|
-
throw new Error("Rate limit exceeded. Please try again later.");
|
|
1768
|
-
try {
|
|
1769
|
-
return await this.circuitBreaker.execute(
|
|
1770
|
-
() => E(r, { ...i, name: a })
|
|
1771
|
-
);
|
|
1772
|
-
} catch (o) {
|
|
1773
|
-
throw o instanceof g ? (l().error(`[SubscriptionChangeManager] Circuit breaker OPEN for ${n}`), new Error("Service temporarily unavailable. Please try again in a few moments.")) : o;
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
/** Change subscription plan (upgrade or downgrade) */
|
|
1777
|
-
async changeSubscription(e) {
|
|
1778
|
-
const r = k(), a = JSON.stringify(e);
|
|
1779
|
-
return this.executeWithResilience(
|
|
1780
|
-
this.rateLimiter,
|
|
1781
|
-
async () => {
|
|
1782
|
-
const n = await this.routeDiscovery.buildUrl("/paywall/v1/subscription/change");
|
|
1783
|
-
l().debug("[SubscriptionChangeManager] Changing subscription:", e);
|
|
1784
|
-
const i = await p(n, {
|
|
1785
|
-
method: "POST",
|
|
1786
|
-
headers: { "Content-Type": "application/json", "Idempotency-Key": r },
|
|
1787
|
-
body: a
|
|
1788
|
-
});
|
|
1789
|
-
if (!i.ok)
|
|
1790
|
-
throw T.fromResponse(
|
|
1791
|
-
i,
|
|
1792
|
-
await w(i, "Failed to change subscription")
|
|
1793
|
-
);
|
|
1794
|
-
return await i.json();
|
|
1795
|
-
},
|
|
1796
|
-
"subscription-change",
|
|
1797
|
-
"plan change",
|
|
1798
|
-
{
|
|
1799
|
-
...v.IDEMPOTENT_WRITE,
|
|
1800
|
-
inFlightKey: `subscription:change:${a}`
|
|
1801
|
-
}
|
|
1802
|
-
);
|
|
1803
|
-
}
|
|
1804
|
-
/** Preview subscription change (get proration details) */
|
|
1805
|
-
async previewChange(e) {
|
|
1806
|
-
return this.executeWithResilience(
|
|
1807
|
-
this.queryRateLimiter,
|
|
1808
|
-
async () => {
|
|
1809
|
-
const r = await this.routeDiscovery.buildUrl("/paywall/v1/subscription/change/preview");
|
|
1810
|
-
l().debug("[SubscriptionChangeManager] Previewing subscription change:", e);
|
|
1811
|
-
const a = await p(r, {
|
|
1812
|
-
method: "POST",
|
|
1813
|
-
headers: { "Content-Type": "application/json" },
|
|
1814
|
-
body: JSON.stringify(e)
|
|
1815
|
-
});
|
|
1816
|
-
if (!a.ok)
|
|
1817
|
-
throw new Error(await w(a, "Failed to preview change"));
|
|
1818
|
-
return await a.json();
|
|
1819
|
-
},
|
|
1820
|
-
"subscription-preview",
|
|
1821
|
-
"change preview"
|
|
1822
|
-
);
|
|
1823
|
-
}
|
|
1824
|
-
/** Get full subscription details */
|
|
1825
|
-
async getDetails(e, r) {
|
|
1826
|
-
return this.executeWithResilience(
|
|
1827
|
-
this.queryRateLimiter,
|
|
1828
|
-
async () => {
|
|
1829
|
-
const a = new URLSearchParams({ resource: e, userId: r }), n = await this.routeDiscovery.buildUrl(`/paywall/v1/subscription/details?${a}`);
|
|
1830
|
-
l().debug("[SubscriptionChangeManager] Getting subscription details:", { resource: e, userId: r });
|
|
1831
|
-
const i = await p(n, {
|
|
1832
|
-
method: "GET",
|
|
1833
|
-
headers: { "Content-Type": "application/json" }
|
|
1834
|
-
});
|
|
1835
|
-
if (!i.ok)
|
|
1836
|
-
throw new Error(await w(i, "Failed to get subscription details"));
|
|
1837
|
-
return await i.json();
|
|
1838
|
-
},
|
|
1839
|
-
"subscription-details",
|
|
1840
|
-
"details"
|
|
1841
|
-
);
|
|
1842
|
-
}
|
|
1843
|
-
/** Cancel a subscription */
|
|
1844
|
-
async cancel(e) {
|
|
1845
|
-
const r = JSON.stringify(e);
|
|
1846
|
-
return this.executeWithResilience(
|
|
1847
|
-
this.rateLimiter,
|
|
1848
|
-
async () => {
|
|
1849
|
-
const a = await this.routeDiscovery.buildUrl("/paywall/v1/subscription/cancel");
|
|
1850
|
-
l().debug("[SubscriptionChangeManager] Canceling subscription:", e);
|
|
1851
|
-
const n = await p(a, {
|
|
1852
|
-
method: "POST",
|
|
1853
|
-
headers: { "Content-Type": "application/json" },
|
|
1854
|
-
body: r
|
|
1855
|
-
});
|
|
1856
|
-
if (!n.ok)
|
|
1857
|
-
throw T.fromResponse(
|
|
1858
|
-
n,
|
|
1859
|
-
await w(n, "Failed to cancel subscription")
|
|
1860
|
-
);
|
|
1861
|
-
return await n.json();
|
|
1862
|
-
},
|
|
1863
|
-
"subscription-cancel",
|
|
1864
|
-
"cancellation",
|
|
1865
|
-
{
|
|
1866
|
-
...v.WRITE_ONCE,
|
|
1867
|
-
inFlightKey: `subscription:cancel:${r}`
|
|
1868
|
-
}
|
|
1869
|
-
);
|
|
1870
|
-
}
|
|
1871
|
-
/** Get Stripe billing portal URL */
|
|
1872
|
-
async getBillingPortalUrl(e) {
|
|
1873
|
-
const r = JSON.stringify(e);
|
|
1874
|
-
return this.executeWithResilience(
|
|
1875
|
-
this.queryRateLimiter,
|
|
1876
|
-
async () => {
|
|
1877
|
-
const a = await this.routeDiscovery.buildUrl("/paywall/v1/subscription/portal");
|
|
1878
|
-
l().debug("[SubscriptionChangeManager] Getting billing portal URL:", e);
|
|
1879
|
-
const n = await p(a, {
|
|
1880
|
-
method: "POST",
|
|
1881
|
-
headers: { "Content-Type": "application/json" },
|
|
1882
|
-
body: r
|
|
1883
|
-
});
|
|
1884
|
-
if (!n.ok)
|
|
1885
|
-
throw T.fromResponse(
|
|
1886
|
-
n,
|
|
1887
|
-
await w(n, "Failed to get billing portal URL")
|
|
1888
|
-
);
|
|
1889
|
-
return await n.json();
|
|
1890
|
-
},
|
|
1891
|
-
"subscription-portal",
|
|
1892
|
-
"portal",
|
|
1893
|
-
{
|
|
1894
|
-
...v.WRITE_ONCE,
|
|
1895
|
-
inFlightKey: `subscription:portal:${r}`
|
|
1896
|
-
}
|
|
1897
|
-
);
|
|
1898
|
-
}
|
|
1899
|
-
}
|
|
1900
|
-
class xt {
|
|
1901
|
-
routeDiscovery;
|
|
1902
|
-
rateLimiter = I(B.PAYMENT);
|
|
1903
|
-
circuitBreaker = Q({
|
|
1904
|
-
failureThreshold: 5,
|
|
1905
|
-
timeout: 1e4,
|
|
1906
|
-
name: "credits-manager"
|
|
1907
|
-
});
|
|
1908
|
-
constructor(e) {
|
|
1909
|
-
this.routeDiscovery = e;
|
|
1910
|
-
}
|
|
1911
|
-
async requestQuote(e, r) {
|
|
1912
|
-
if (!this.rateLimiter.tryConsume())
|
|
1913
|
-
throw new Error("Rate limit exceeded for credits quote. Please try again later.");
|
|
1914
|
-
try {
|
|
1915
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1916
|
-
async () => {
|
|
1917
|
-
const a = await this.routeDiscovery.buildUrl("/paywall/v1/quote");
|
|
1918
|
-
l().debug("[CreditsManager] Requesting quote");
|
|
1919
|
-
const n = await p(a, {
|
|
1920
|
-
method: "POST",
|
|
1921
|
-
headers: { "Content-Type": "application/json" },
|
|
1922
|
-
body: JSON.stringify({ resource: e, couponCode: r })
|
|
1923
|
-
});
|
|
1924
|
-
if (n.status === 402)
|
|
1925
|
-
return (await n.json()).credits || null;
|
|
1926
|
-
if (!n.ok) {
|
|
1927
|
-
const i = await w(n, "Failed to get credits quote");
|
|
1928
|
-
throw new Error(i);
|
|
1929
|
-
}
|
|
1930
|
-
return null;
|
|
1931
|
-
},
|
|
1932
|
-
{ ...v.STANDARD, name: "credits-quote" }
|
|
1933
|
-
));
|
|
1934
|
-
} catch (a) {
|
|
1935
|
-
throw a instanceof g ? (l().error("[CreditsManager] Circuit breaker is OPEN - credits service unavailable"), new Error("Credits service is temporarily unavailable. Please try again in a few moments.")) : a;
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
async requestCartQuote(e, r) {
|
|
1939
|
-
if (!this.rateLimiter.tryConsume())
|
|
1940
|
-
throw new Error("Rate limit exceeded for cart credits quote. Please try again later.");
|
|
1941
|
-
try {
|
|
1942
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1943
|
-
async () => {
|
|
1944
|
-
const a = await this.routeDiscovery.buildUrl("/paywall/v1/cart/quote");
|
|
1945
|
-
l().debug("[CreditsManager] Requesting cart quote for items:", e.length);
|
|
1946
|
-
const n = await p(a, {
|
|
1947
|
-
method: "POST",
|
|
1948
|
-
headers: { "Content-Type": "application/json" },
|
|
1949
|
-
body: JSON.stringify({ items: e, couponCode: r })
|
|
1950
|
-
});
|
|
1951
|
-
if (n.status === 402 || n.ok) {
|
|
1952
|
-
const o = await n.json();
|
|
1953
|
-
return o.credits ? {
|
|
1954
|
-
cartId: o.cartId,
|
|
1955
|
-
credits: o.credits
|
|
1956
|
-
} : null;
|
|
1957
|
-
}
|
|
1958
|
-
const i = await w(n, "Failed to get cart credits quote");
|
|
1959
|
-
throw new Error(i);
|
|
1960
|
-
},
|
|
1961
|
-
{ ...v.STANDARD, name: "credits-cart-quote" }
|
|
1962
|
-
));
|
|
1963
|
-
} catch (a) {
|
|
1964
|
-
throw a instanceof g ? new Error("Credits service is temporarily unavailable. Please try again in a few moments.") : a;
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
/**
|
|
1968
|
-
* Create a hold on user's credits
|
|
1969
|
-
* Requires Authorization header with cedros-login JWT token
|
|
1970
|
-
*/
|
|
1971
|
-
async createHold(e) {
|
|
1972
|
-
const { resource: r, couponCode: a, authToken: n } = e;
|
|
1973
|
-
if (!this.rateLimiter.tryConsume())
|
|
1974
|
-
throw new Error("Rate limit exceeded for credits hold. Please try again later.");
|
|
1975
|
-
const i = k(), o = JSON.stringify({ resource: r, couponCode: a });
|
|
1976
|
-
try {
|
|
1977
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
1978
|
-
async () => {
|
|
1979
|
-
const s = await this.routeDiscovery.buildUrl("/paywall/v1/credits/hold");
|
|
1980
|
-
l().debug("[CreditsManager] Creating hold");
|
|
1981
|
-
const c = await p(s, {
|
|
1982
|
-
method: "POST",
|
|
1983
|
-
headers: {
|
|
1984
|
-
"Content-Type": "application/json",
|
|
1985
|
-
Authorization: `Bearer ${n}`,
|
|
1986
|
-
"Idempotency-Key": i
|
|
1987
|
-
},
|
|
1988
|
-
body: o
|
|
1989
|
-
});
|
|
1990
|
-
if (!c.ok) {
|
|
1991
|
-
const u = await w(c, "Failed to create credits hold");
|
|
1992
|
-
throw T.fromResponse(c, u);
|
|
1993
|
-
}
|
|
1994
|
-
return await c.json();
|
|
1995
|
-
},
|
|
1996
|
-
{
|
|
1997
|
-
...v.IDEMPOTENT_WRITE,
|
|
1998
|
-
name: "credits-create-hold",
|
|
1999
|
-
inFlightKey: `credits:create-hold:${n}:${o}`
|
|
2000
|
-
}
|
|
2001
|
-
));
|
|
2002
|
-
} catch (s) {
|
|
2003
|
-
throw s instanceof g ? new Error("Credits service is temporarily unavailable. Please try again in a few moments.") : s;
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
/**
|
|
2007
|
-
* Create a hold on user's credits for a cart
|
|
2008
|
-
* Requires Authorization header with cedros-login JWT token
|
|
2009
|
-
*/
|
|
2010
|
-
async createCartHold(e) {
|
|
2011
|
-
const { cartId: r, authToken: a } = e;
|
|
2012
|
-
if (!this.rateLimiter.tryConsume())
|
|
2013
|
-
throw new Error("Rate limit exceeded for cart credits hold. Please try again later.");
|
|
2014
|
-
const n = k();
|
|
2015
|
-
try {
|
|
2016
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
2017
|
-
async () => {
|
|
2018
|
-
const i = await this.routeDiscovery.buildUrl(`/paywall/v1/cart/${encodeURIComponent(r)}/credits/hold`);
|
|
2019
|
-
l().debug("[CreditsManager] Creating cart hold for cart:", r);
|
|
2020
|
-
const o = await p(i, {
|
|
2021
|
-
method: "POST",
|
|
2022
|
-
headers: {
|
|
2023
|
-
"Content-Type": "application/json",
|
|
2024
|
-
Authorization: `Bearer ${a}`,
|
|
2025
|
-
"Idempotency-Key": n
|
|
2026
|
-
},
|
|
2027
|
-
body: JSON.stringify({})
|
|
2028
|
-
});
|
|
2029
|
-
if (!o.ok) {
|
|
2030
|
-
const s = await w(o, "Failed to create cart credits hold");
|
|
2031
|
-
throw T.fromResponse(o, s);
|
|
2032
|
-
}
|
|
2033
|
-
return await o.json();
|
|
2034
|
-
},
|
|
2035
|
-
{
|
|
2036
|
-
...v.IDEMPOTENT_WRITE,
|
|
2037
|
-
name: "credits-create-cart-hold",
|
|
2038
|
-
inFlightKey: `credits:create-cart-hold:${a}:${r}`
|
|
2039
|
-
}
|
|
2040
|
-
));
|
|
2041
|
-
} catch (i) {
|
|
2042
|
-
throw i instanceof g ? new Error("Credits service is temporarily unavailable. Please try again in a few moments.") : i;
|
|
2043
|
-
}
|
|
2044
|
-
}
|
|
2045
|
-
async authorizePayment(e) {
|
|
2046
|
-
const { resource: r, holdId: a, couponCode: n, authToken: i, metadata: o } = e;
|
|
2047
|
-
if (!this.rateLimiter.tryConsume())
|
|
2048
|
-
return {
|
|
2049
|
-
success: !1,
|
|
2050
|
-
error: "Rate limit exceeded for credits authorization. Please try again later.",
|
|
2051
|
-
errorCode: "rate_limit_exceeded"
|
|
2052
|
-
};
|
|
2053
|
-
const s = k(), c = JSON.stringify({
|
|
2054
|
-
resource: r,
|
|
2055
|
-
holdId: a,
|
|
2056
|
-
couponCode: n,
|
|
2057
|
-
...o && { metadata: o }
|
|
2058
|
-
});
|
|
2059
|
-
try {
|
|
2060
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
2061
|
-
async () => {
|
|
2062
|
-
const u = await this.routeDiscovery.buildUrl("/paywall/v1/credits/authorize");
|
|
2063
|
-
l().debug("[CreditsManager] Authorizing payment");
|
|
2064
|
-
const f = await p(u, {
|
|
2065
|
-
method: "POST",
|
|
2066
|
-
headers: {
|
|
2067
|
-
"Content-Type": "application/json",
|
|
2068
|
-
Authorization: `Bearer ${i}`,
|
|
2069
|
-
"Idempotency-Key": s
|
|
2070
|
-
},
|
|
2071
|
-
body: c
|
|
2072
|
-
});
|
|
2073
|
-
if (!f.ok) {
|
|
2074
|
-
const y = await f.json().catch(() => ({}));
|
|
2075
|
-
throw T.fromResponse(
|
|
2076
|
-
f,
|
|
2077
|
-
y.error?.message || "Credits authorization failed"
|
|
2078
|
-
);
|
|
2079
|
-
}
|
|
2080
|
-
return {
|
|
2081
|
-
success: !0,
|
|
2082
|
-
transactionId: (await f.json()).transactionId
|
|
2083
|
-
};
|
|
2084
|
-
},
|
|
2085
|
-
{
|
|
2086
|
-
...v.IDEMPOTENT_WRITE,
|
|
2087
|
-
name: "credits-authorize",
|
|
2088
|
-
inFlightKey: `credits:authorize:${i}:${c}`
|
|
2089
|
-
}
|
|
2090
|
-
));
|
|
2091
|
-
} catch (u) {
|
|
2092
|
-
return u instanceof g ? {
|
|
2093
|
-
success: !1,
|
|
2094
|
-
error: "Credits service is temporarily unavailable. Please try again in a few moments.",
|
|
2095
|
-
errorCode: "service_unavailable"
|
|
2096
|
-
} : {
|
|
2097
|
-
success: !1,
|
|
2098
|
-
error: O(u, "Credits authorization failed"),
|
|
2099
|
-
errorCode: "authorization_failed"
|
|
2100
|
-
};
|
|
2101
|
-
}
|
|
2102
|
-
}
|
|
2103
|
-
async authorizeCartPayment(e) {
|
|
2104
|
-
const { cartId: r, holdId: a, authToken: n, metadata: i } = e;
|
|
2105
|
-
if (!this.rateLimiter.tryConsume())
|
|
2106
|
-
return {
|
|
2107
|
-
success: !1,
|
|
2108
|
-
error: "Rate limit exceeded for cart credits authorization. Please try again later.",
|
|
2109
|
-
errorCode: "rate_limit_exceeded"
|
|
2110
|
-
};
|
|
2111
|
-
const o = k(), s = JSON.stringify({
|
|
2112
|
-
holdId: a,
|
|
2113
|
-
...i && { metadata: i }
|
|
2114
|
-
});
|
|
2115
|
-
try {
|
|
2116
|
-
return await this.circuitBreaker.execute(async () => await E(
|
|
2117
|
-
async () => {
|
|
2118
|
-
const c = await this.routeDiscovery.buildUrl(`/paywall/v1/cart/${encodeURIComponent(r)}/credits/authorize`);
|
|
2119
|
-
l().debug("[CreditsManager] Authorizing cart payment for cart:", r);
|
|
2120
|
-
const u = await p(c, {
|
|
2121
|
-
method: "POST",
|
|
2122
|
-
headers: {
|
|
2123
|
-
"Content-Type": "application/json",
|
|
2124
|
-
Authorization: `Bearer ${n}`,
|
|
2125
|
-
"Idempotency-Key": o
|
|
2126
|
-
},
|
|
2127
|
-
body: s
|
|
2128
|
-
});
|
|
2129
|
-
if (!u.ok) {
|
|
2130
|
-
const h = await u.json().catch((y) => (l().error("[CreditsManager] Failed to parse error response JSON:", y, {
|
|
2131
|
-
cartId: r,
|
|
2132
|
-
status: u.status,
|
|
2133
|
-
statusText: u.statusText
|
|
2134
|
-
}), {}));
|
|
2135
|
-
throw T.fromResponse(
|
|
2136
|
-
u,
|
|
2137
|
-
h.error?.message || "Cart credits authorization failed"
|
|
2138
|
-
);
|
|
2139
|
-
}
|
|
2140
|
-
return {
|
|
2141
|
-
success: !0,
|
|
2142
|
-
transactionId: (await u.json()).transactionId
|
|
2143
|
-
};
|
|
2144
|
-
},
|
|
2145
|
-
{
|
|
2146
|
-
...v.IDEMPOTENT_WRITE,
|
|
2147
|
-
name: "credits-cart-authorize",
|
|
2148
|
-
inFlightKey: `credits:cart-authorize:${n}:${r}:${s}`
|
|
2149
|
-
}
|
|
2150
|
-
));
|
|
2151
|
-
} catch (c) {
|
|
2152
|
-
return c instanceof g ? {
|
|
2153
|
-
success: !1,
|
|
2154
|
-
error: "Credits service is temporarily unavailable. Please try again in a few moments.",
|
|
2155
|
-
errorCode: "service_unavailable"
|
|
2156
|
-
} : {
|
|
2157
|
-
success: !1,
|
|
2158
|
-
error: O(c, "Cart credits authorization failed"),
|
|
2159
|
-
errorCode: "authorization_failed"
|
|
2160
|
-
};
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
async releaseHold(e, r) {
|
|
2164
|
-
if (e)
|
|
2165
|
-
try {
|
|
2166
|
-
await this.circuitBreaker.execute(async () => {
|
|
2167
|
-
const a = await this.routeDiscovery.buildUrl(`/paywall/v1/credits/hold/${encodeURIComponent(e)}/release`), n = await p(a, {
|
|
2168
|
-
method: "POST",
|
|
2169
|
-
headers: {
|
|
2170
|
-
Authorization: `Bearer ${r}`,
|
|
2171
|
-
"Idempotency-Key": k()
|
|
2172
|
-
}
|
|
2173
|
-
});
|
|
2174
|
-
if (!n.ok) {
|
|
2175
|
-
const i = await w(n, "Failed to release credits hold");
|
|
2176
|
-
throw new Error(i);
|
|
2177
|
-
}
|
|
2178
|
-
});
|
|
2179
|
-
} catch (a) {
|
|
2180
|
-
throw a instanceof g ? new Error("Credits service is temporarily unavailable. Please try again in a few moments.") : a;
|
|
2181
|
-
}
|
|
2182
|
-
}
|
|
2183
|
-
/**
|
|
2184
|
-
* Process a complete credits payment (convenience method)
|
|
2185
|
-
* Combines createHold + authorizePayment in one call
|
|
2186
|
-
*
|
|
2187
|
-
* @param resource - Resource being purchased
|
|
2188
|
-
* @param authToken - JWT token from cedros-login
|
|
2189
|
-
* @param couponCode - Optional coupon code
|
|
2190
|
-
* @param metadata - Optional metadata
|
|
2191
|
-
*/
|
|
2192
|
-
async processPayment(e, r, a, n) {
|
|
2193
|
-
let i = null;
|
|
2194
|
-
try {
|
|
2195
|
-
i = (await this.createHold({ resource: e, couponCode: a, authToken: r })).holdId;
|
|
2196
|
-
const s = await this.authorizePayment({
|
|
2197
|
-
resource: e,
|
|
2198
|
-
holdId: i,
|
|
2199
|
-
couponCode: a,
|
|
2200
|
-
authToken: r,
|
|
2201
|
-
metadata: n
|
|
2202
|
-
});
|
|
2203
|
-
if (!s.success && i)
|
|
2204
|
-
try {
|
|
2205
|
-
await this.releaseHold(i, r);
|
|
2206
|
-
} catch (c) {
|
|
2207
|
-
l().warn("[CreditsManager] Failed to release hold after auth failure:", c);
|
|
2208
|
-
}
|
|
2209
|
-
return {
|
|
2210
|
-
success: s.success,
|
|
2211
|
-
transactionId: s.transactionId,
|
|
2212
|
-
error: s.error
|
|
2213
|
-
};
|
|
2214
|
-
} catch (o) {
|
|
2215
|
-
if (i)
|
|
2216
|
-
try {
|
|
2217
|
-
await this.releaseHold(i, r);
|
|
2218
|
-
} catch (s) {
|
|
2219
|
-
l().warn("[CreditsManager] Failed to release hold after payment failure:", s);
|
|
2220
|
-
}
|
|
2221
|
-
return {
|
|
2222
|
-
success: !1,
|
|
2223
|
-
error: O(o, "Credits payment failed")
|
|
2224
|
-
};
|
|
2225
|
-
}
|
|
2226
|
-
}
|
|
2227
|
-
async getBalance(e) {
|
|
2228
|
-
try {
|
|
2229
|
-
return await this.circuitBreaker.execute(async () => {
|
|
2230
|
-
const r = await this.routeDiscovery.buildUrl("/paywall/v1/credits/balance"), a = await p(r, {
|
|
2231
|
-
method: "GET",
|
|
2232
|
-
headers: { Authorization: `Bearer ${e}` }
|
|
2233
|
-
});
|
|
2234
|
-
if (!a.ok) {
|
|
2235
|
-
const n = await w(a, "Failed to fetch credits balance");
|
|
2236
|
-
throw new Error(n);
|
|
2237
|
-
}
|
|
2238
|
-
return await a.json();
|
|
2239
|
-
});
|
|
2240
|
-
} catch (r) {
|
|
2241
|
-
throw r instanceof g ? new Error("Credits service is temporarily unavailable. Please try again in a few moments.") : r;
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
}
|
|
2245
|
-
class kt {
|
|
2246
|
-
serverUrl;
|
|
2247
|
-
getLogger;
|
|
2248
|
-
fetchWithTimeout;
|
|
2249
|
-
routePrefix = null;
|
|
2250
|
-
discoveryPromise = null;
|
|
2251
|
-
failedDiscoveryAt = null;
|
|
2252
|
-
maxRetries = 2;
|
|
2253
|
-
baseDelayMs = 1e3;
|
|
2254
|
-
discoveryTimeoutMs = 2e3;
|
|
2255
|
-
failedDiscoveryTtlMs = 3e4;
|
|
2256
|
-
constructor(e, r) {
|
|
2257
|
-
this.serverUrl = e.replace(/\/+$/, ""), this.getLogger = r.getLogger, this.fetchWithTimeout = r.fetchWithTimeout;
|
|
2258
|
-
}
|
|
2259
|
-
async discoverPrefix() {
|
|
2260
|
-
if (this.routePrefix !== null)
|
|
2261
|
-
return this.routePrefix;
|
|
2262
|
-
if (this.discoveryPromise)
|
|
2263
|
-
return this.discoveryPromise;
|
|
2264
|
-
if (this.failedDiscoveryAt !== null && Date.now() - this.failedDiscoveryAt < this.failedDiscoveryTtlMs)
|
|
2265
|
-
return "";
|
|
2266
|
-
const e = (async () => {
|
|
2267
|
-
let r = 0;
|
|
2268
|
-
for (; r < this.maxRetries; )
|
|
2269
|
-
try {
|
|
2270
|
-
const a = await this.fetchWithTimeout(
|
|
2271
|
-
`${this.serverUrl}/cedros-health`,
|
|
2272
|
-
{},
|
|
2273
|
-
this.discoveryTimeoutMs
|
|
2274
|
-
);
|
|
2275
|
-
if (!a.ok) {
|
|
2276
|
-
if (a.status >= 400 && a.status < 500)
|
|
2277
|
-
return this.getLogger().warn(
|
|
2278
|
-
`Route discovery received ${a.status} - not retrying client error`
|
|
2279
|
-
), this.failedDiscoveryAt = Date.now(), "";
|
|
2280
|
-
throw new Error(`Health check returned ${a.status}`);
|
|
2281
|
-
}
|
|
2282
|
-
const n = await a.json(), i = String(n.routePrefix ?? "");
|
|
2283
|
-
return this.routePrefix = i, this.failedDiscoveryAt = null, this.getLogger().debug("Route discovery successful, prefix:", i || "(empty)"), i;
|
|
2284
|
-
} catch (a) {
|
|
2285
|
-
if (r++, r >= this.maxRetries)
|
|
2286
|
-
return this.getLogger().warn(
|
|
2287
|
-
`Route discovery failed after ${r} attempts, using empty prefix for this request:`,
|
|
2288
|
-
a
|
|
2289
|
-
), this.failedDiscoveryAt = Date.now(), "";
|
|
2290
|
-
const n = this.baseDelayMs * Math.pow(2, r - 1);
|
|
2291
|
-
this.getLogger().warn(
|
|
2292
|
-
`Route discovery failed (attempt ${r}/${this.maxRetries}), retrying in ${n}ms:`,
|
|
2293
|
-
a
|
|
2294
|
-
), await new Promise((i) => setTimeout(i, n));
|
|
2295
|
-
}
|
|
2296
|
-
return "";
|
|
2297
|
-
})();
|
|
2298
|
-
this.discoveryPromise = e;
|
|
2299
|
-
try {
|
|
2300
|
-
return await this.discoveryPromise;
|
|
2301
|
-
} finally {
|
|
2302
|
-
this.discoveryPromise === e && (this.discoveryPromise = null);
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
async buildUrl(e) {
|
|
2306
|
-
const r = await this.discoverPrefix(), a = e.startsWith("/") ? e : `/${e}`;
|
|
2307
|
-
return `${this.serverUrl}${r}${a}`;
|
|
2308
|
-
}
|
|
2309
|
-
reset() {
|
|
2310
|
-
this.routePrefix = null, this.discoveryPromise = null, this.failedDiscoveryAt = null;
|
|
2311
|
-
}
|
|
2312
|
-
}
|
|
2313
|
-
class Rt extends kt {
|
|
2314
|
-
constructor(e) {
|
|
2315
|
-
super(e, { getLogger: l, fetchWithTimeout: p });
|
|
2316
|
-
}
|
|
2317
|
-
}
|
|
2318
|
-
let ee = null;
|
|
2319
|
-
async function Mt() {
|
|
2320
|
-
return ee || (ee = (await import("./WalletManager-BIwH8Dw_.mjs")).WalletManager), ee;
|
|
2321
|
-
}
|
|
2322
|
-
const X = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map();
|
|
2323
|
-
function qe(t, e, r, a, n, i) {
|
|
2324
|
-
return JSON.stringify({
|
|
2325
|
-
stripePublicKey: t,
|
|
2326
|
-
serverUrl: e,
|
|
2327
|
-
solanaCluster: r,
|
|
2328
|
-
solanaEndpoint: a || "",
|
|
2329
|
-
dangerouslyAllowUnknownMint: n || !1,
|
|
2330
|
-
complianceCheck: i || !1
|
|
2331
|
-
});
|
|
2332
|
-
}
|
|
2333
|
-
async function Dt(t, e, r, a, n, i) {
|
|
2334
|
-
const o = qe(
|
|
2335
|
-
t,
|
|
2336
|
-
e,
|
|
2337
|
-
r,
|
|
2338
|
-
a,
|
|
2339
|
-
n,
|
|
2340
|
-
i
|
|
2341
|
-
);
|
|
2342
|
-
let s = X.get(o);
|
|
2343
|
-
if (s)
|
|
2344
|
-
return s.refCount++, l().debug(
|
|
2345
|
-
`[ManagerCache] Reusing cached managers (refCount: ${s.refCount}):`,
|
|
2346
|
-
{ stripePublicKey: t.slice(0, 10) + "...", serverUrl: e }
|
|
2347
|
-
), s;
|
|
2348
|
-
const c = te.get(o);
|
|
2349
|
-
if (c)
|
|
2350
|
-
return s = await c, s.refCount++, l().debug(
|
|
2351
|
-
`[ManagerCache] Reusing in-flight managers (refCount: ${s.refCount}):`,
|
|
2352
|
-
{ stripePublicKey: t.slice(0, 10) + "...", serverUrl: e }
|
|
2353
|
-
), s;
|
|
2354
|
-
l().debug(
|
|
2355
|
-
"[ManagerCache] Creating new manager instances:",
|
|
2356
|
-
{ stripePublicKey: t.slice(0, 10) + "...", serverUrl: e }
|
|
2357
|
-
);
|
|
2358
|
-
const u = (async () => {
|
|
2359
|
-
const f = new Rt(e), h = new ht(t, f, i ?? !1), y = new Pt(f), d = await Mt(), m = new d(
|
|
2360
|
-
r,
|
|
2361
|
-
a,
|
|
2362
|
-
n ?? !1
|
|
2363
|
-
), A = new St(t, f), b = new Tt(f), x = new xt(f);
|
|
2364
|
-
return {
|
|
2365
|
-
stripeManager: h,
|
|
2366
|
-
x402Manager: y,
|
|
2367
|
-
walletManager: m,
|
|
2368
|
-
subscriptionManager: A,
|
|
2369
|
-
subscriptionChangeManager: b,
|
|
2370
|
-
creditsManager: x,
|
|
2371
|
-
routeDiscovery: f,
|
|
2372
|
-
refCount: 1
|
|
2373
|
-
};
|
|
2374
|
-
})();
|
|
2375
|
-
te.set(o, u);
|
|
2376
|
-
try {
|
|
2377
|
-
return s = await u, X.set(o, s), s;
|
|
2378
|
-
} finally {
|
|
2379
|
-
te.delete(o);
|
|
2380
|
-
}
|
|
2381
|
-
}
|
|
2382
|
-
function we(t, e, r, a, n, i) {
|
|
2383
|
-
const o = qe(
|
|
2384
|
-
t,
|
|
2385
|
-
e,
|
|
2386
|
-
r,
|
|
2387
|
-
a,
|
|
2388
|
-
n,
|
|
2389
|
-
i
|
|
2390
|
-
), s = X.get(o);
|
|
2391
|
-
if (!s) {
|
|
2392
|
-
l().warn("[ManagerCache] Attempted to release non-existent managers:", { cacheKey: o });
|
|
2393
|
-
return;
|
|
2394
|
-
}
|
|
2395
|
-
s.refCount--, l().debug(
|
|
2396
|
-
`[ManagerCache] Released manager reference (refCount: ${s.refCount}):`,
|
|
2397
|
-
{ stripePublicKey: t.slice(0, 10) + "...", serverUrl: e }
|
|
2398
|
-
), s.refCount <= 0 && (X.delete(o), l().debug("[ManagerCache] Removed managers from cache (refCount reached 0)"));
|
|
2399
|
-
}
|
|
2400
|
-
const Ot = "data:image/webp;base64,UklGRnIIAABXRUJQVlA4WAoAAAAYAAAAOwAAOwAAQUxQSK4BAAABkHPbtrE9+z73/RTbqWw7Lf+BbbNKbTudbZe2qy+VbVv3PmeHj05G6ohg4LaRounNMtN1voB42ABA5R7TNlx5+O7du9e3Tiwb0b4EgFyAOCQM1Z16+DWFUZC7m3uVB2zKQGBhe+77RGHonJffCL1zQuHDxQ1hrEmTatDjHIXOC2MgzpNf1tVJkWgsGhyihI7JIE74aUYp2ITFAoz9QO+ZAs7zanvkEilKbIkMJS5ANwoJmrCodYVOmBqh5zIEJjZc9xods4A4rrPGxGitrJSU71yNyH4Myl7JTEl+5zzYSH9nlkrxHBzxWUzLVEnhh+YI/gq3+UphpvA8m/s7/wg9M4bjFNg/0vplrxQ+rQEDg/xihmT23jxYJZ8UPq8OA5z77Wt405FDR4poSMjiAJhPRxUIu8D+UVonOhfNPEVHPM9juFacwo+1V6kJQ3Y9Sa8ljhPuUvRk4UdNWU9ST3b9n0W3iG5DumdS9y7o3kHVu6/75ii/dbpvrO7brvtPUf2X6f5DVf/dmpxBmauociRVbqbKCXW5qCoHVuXempxf1dZQtXFUbat/yKZTtSUBVlA4INwFAABwGgCdASo8ADwAPm0qj0WkIqEZ+zYAQAbEtgBOmZoZF+E8zGoP3X8VbcdLvma8t+jH0E+YB+ofSA8wH7VdQv0AP75/iOsG9ADy3/Y5/b/91fgI/Y7MOesb0e/q+TUR1vt7VO6mwG0imO70GM5/0P7BX6qelv7EP209lz9oDRea09ZR+SjhX7sBu/ZS7tG917rPgI3Q7XsB7luy2hAg/95C2Z1L362OH1oFziDY/K5gWoSytSAtiKvA/jW1MehBzdLzJfszPPBvGa15IYwIVRTjO2Hz5ZS9HjLMehwAAP64SgjD3qeg6NRe/Ok+iFhrG3pgglCfbam3yBaDUH36sUiQx0PB1ZZyOHq0ky+f97h6tJMvo0p9LkfXecWOFJ8J5G7yRPuL4tzGLT09QulTJw42xp2hd+lMgIa51XoHx/iftn8B2D3k92H5jOQr+uIXFHHK5FpcTG+qGEF+np0LiQa+vdW7/+ZzOLVRf7jR5X3ANPt93Ng92DW7NflVr6kMr88O/v2ZNb0vtgao2Am/R3CDKiNq89f86CT6r2L2g1oTui7H3E1yhSPQpEOz01I3fhfiMMv4weqKuoedxn/xLg5uzHa6Gte4C/dQYkG3ZFSy4CXQtRjftBrjX/Oj+HpSUPDsv0wPW+ml5NbBKDCj2f3SD8TVMf2ZfHrOkR602RVk2UmKC+H0Y9iK6k98vsgPINtz0II8X7Mj2nJkTC6IMLuQ8dNTUq9VXOnhXrdhNZoaH94ePo6baBl3hTGFAnD3/b+gR/vtbqV7wktuX6fpnjeTBe/Drp6z3neeANj/aX4CsU9w67nwYOjZhueCjxaDKUnNjLPjI1e0BoTbcOzOQ0wHJHZJ+Pt608StBu4HiJ8NjH46fnvXL3yiMoSvkAuwCE1AakA+eU1u3unyjl1/MnZQmbp8fzfsfrFesehLPcIkYdCiZ+52QbmINNTjEsvjuBuZRubBE+Laihppsxoo4efGIo0xkw0etu1+yzvkqp88w3pBq0mRl13gnnc+2zl6SmhwgmNFbz+F8qAqmdfJL8iaNSGEWlPlpczDDe62GBZMlBhQmq/XCn/1b+VazHvJXkoIFDF+wktMg+rKfLyfTlXdK0cs+Kn8h+rjMakkf3WLo1TftMLn+O+x/Gat+BGstJrM1xvCSSnHQY+NV4B4gRqyZ55gRNnqN/0lWrATOcHUaGXpkTIM/yxFjxcePcSFo+t2aJ5lShtVukETzRxaIXgRkpROeWQHWpTHOaexmXOzF0b833qJSoXMk2zB/uMrgDzKd7d3ohUz8Ra08WYKlAuMQD08bF4+jUepEspqPLoYLQ73TfmL+1LwKxyTV3gEu6WnxBPWPLnYIGYN9U47ZNlB+NgHgYtKTyii6060RAG+wN32WUVFxCZw0HMHnHFgwxD34L/anlpS7mOrjKgyuGYhFC7iHqTQHuoAO1ekBHV+rndnbETKfa1F7LxNLYq+dmJyytmQrJUCGjelorI1m/TMQNiFVrY4FCI1Gl2W1JsZsw9zA+Bh3JmjkC0H5/0JV6JotNMatJIZ4v5PqwJe3r8xd+FNS3ynccdu+xtVdc27qwVdoomciZD5oXYey9KAFSAKO594sBKZNWUJTLXnt0BJbdF8FkQYvg3DQajYY2p+ixd5Ag7o92gw0pVVDDOP+WQxiEmKqgWJyTBsnsBk2Bxi2Unsv8S/4PmE8Hy/vy+Mij+aTAKZvg716IHfHX0/JMeFfmAnsZ39Q0qkfdPtq6+CxbGZ7wKDsK/8l/MVGuyd6faJFt5wyoOXuNrr3JC9EoBmjcOzkVw/6RNP49poZ1xzsX3q7B4HGfI/XSfRQq3HeZ2j12d0E3gCAube4oExaT1sx/v8F+f61QOsGdSaqM2im6qOGkSRkrRQ7L8hvS8vEYJeVkAbFvX5ov7e/egYYNToMHj651c5/rCVYtB9Ned6GvGN8R0x3t7+lsf8+ofhHRzpyvwxd6c5pREZVOKnXzplhJ61mki4JmAAAABFWElGugAAAEV4aWYAAElJKgAIAAAABgASAQMAAQAAAAEAAAAaAQUAAQAAAFYAAAAbAQUAAQAAAF4AAAAoAQMAAQAAAAIAAAATAgMAAQAAAAEAAABphwQAAQAAAGYAAAAAAAAASAAAAAEAAABIAAAAAQAAAAYAAJAHAAQAAAAwMjEwAZEHAAQAAAABAgMAAKAHAAQAAAAwMTAwAaADAAEAAAD//wAAAqAEAAEAAAA8AAAAA6AEAAEAAAA8AAAAAAAAAA==", It = "data:image/svg+xml,%3csvg%20width='868'%20height='868'%20viewBox='0%200%20868%20868'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3ccircle%20cx='434'%20cy='434'%20r='434'%20fill='%231B262D'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M234.563%20184H640.697C650.387%20184%20659.339%20189.164%20664.172%20197.542L782.495%20402.657C788.631%20413.294%20786.808%20426.72%20778.056%20435.346L452.368%20756.327C441.818%20766.724%20424.846%20766.724%20414.296%20756.327L89.0484%20435.78C80.0927%20426.954%2078.4157%20413.136%2085.0013%20402.433L211.48%20196.884C216.405%20188.879%20225.146%20184%20234.563%20184ZM588.257%20275.577V333.129H472.567V373.032C553.82%20377.296%20614.782%20394.81%20615.234%20415.802L615.231%20459.563C614.779%20480.556%20553.82%20498.069%20472.567%20502.333V600.259H395.746V502.333C314.492%20498.069%20253.531%20480.555%20253.078%20459.563L253.081%20415.802C253.533%20394.81%20314.492%20377.296%20395.746%20373.032V333.129H280.055V275.577H588.257ZM434.156%20472.268C520.868%20472.268%20593.345%20457.459%20611.082%20437.683C596.041%20420.912%20541.636%20407.713%20472.567%20404.089V445.867C460.187%20446.516%20447.336%20446.858%20434.156%20446.858C420.976%20446.858%20408.125%20446.516%20395.746%20445.867V404.089C326.676%20407.713%20272.271%20420.912%20257.23%20437.683C274.968%20457.459%20347.444%20472.268%20434.156%20472.268Z'%20fill='%23009393'/%3e%3c/svg%3e", Bt = "data:image/webp;base64,UklGRqwEAABXRUJQVlA4WAoAAAAYAAAAOwAAOwAAQUxQSL8BAAABkGvbtmlLc5997yvbmW19gBnbDm2kjF5UmW3bthXZVZFdZ+81r+87Z1XlEaHIbSNlMstwos4XUBSTLAFQo/u01Zdf/yLDDze3zB/YwADJEoOoJAKg7oTdH4SF+XxiZlMgSESzwAJdVn2iUJzzOUMiLhQKf+/va2FtBLMBuu1zpHcsincUXhtoTKLsCTVX/KF3wrLhPLm/OWzZtjQWfZ7RhYyAC/lxMowpSzJYJAyFkZDQc21FBMUT7BqGjpHxf3m+XlEPUHE/f3vGgPzmw4awRUaTexkyJhwfNShctVgZXyJDXq4CUyjNy6Y4fVOBIkAPR2GcOE7Jm2NQ/RE9YzXht3a5VYvlOX0xF0fy+tp/ozBuQg6DzZYb6Bi7ed4rB5Mp/1Co4cNhLUo1StLxDIDqrynUoRswiF6nFnIxsDpnZ5WBW0GFZ1qZ8HfLDk5txHHsGDpSa6B0cXZEa+DsTr1M+P4qPdXwjynU4+1/a7oN3Sm6G+meSd27oHsHde++7puj+tYpv7G6b7vun6L7l6n+oZp/t7JmUNUqqhpJV5upakJVLaqqgVW1t6rmV401NGMc1djqH4rpIseSfyPFkgAAVlA4IAQCAABQDACdASo8ADwAPm0yk0akIyGhJgzogA2JaQAThroHvLxu+aPf5G2BYxv+B6XHzx6GPon/o+qz/tOAA/TM82gR0vnExWoiQRM36jlg2UIvwCSqySErzuguz9EP2x/7hsNazr91aIworWI7AAD+/TZ+6Ipl444OdT+2wU0Ov+T8oJuVP/vUbT/w1Jsv6Awnl6rvF/xetfOPt3gTQZZi0Y/AOx563J7CJkqTR/fc/n34zyeKzR80fhfv4ef+Hjhz/CX5aQo+58zg/FdE+7bLoophGfG0szI513EH+q+Gc73H1PFdJYf7CF8v5dhr3tMwEVX5Ji2ZxejK8xrf/E6nVXqlA4DrYNRP09InHc+fEqO/fH8xr+rMf4y1F9TOnwVffZblLoTP6lot0m/sh7sTiDQr0mIA8TiHoOffGDG6KzV+B3239udfhzD740gkRi/m53abX0Ku3vAgadgFFqL0vk8M/4aI+cI+0fbLW17mWGeMu21wSRRQiv5iNgGKR3vEGXAItcLDft1uUzWAfbe1X3zK/ymT7bA/76PB6UUknm+Y5MM4osurUXU/k7P38pN/3slnGfpFzjl4c3USY4mH9ZCJYUuC/kGEnq/yRPalPdODNFvW6s8MiQeQejYNRY0LsJ0WXkK8vXiDmihCivYAOPoSovesL7on+WAArDNM/BcQSQvCYABFWElGugAAAEV4aWYAAElJKgAIAAAABgASAQMAAQAAAAEAAAAaAQUAAQAAAFYAAAAbAQUAAQAAAF4AAAAoAQMAAQAAAAIAAAATAgMAAQAAAAEAAABphwQAAQAAAGYAAAAAAAAASAAAAAEAAABIAAAAAQAAAAYAAJAHAAQAAAAwMjEwAZEHAAQAAAABAgMAAKAHAAQAAAAwMTAwAaADAAEAAAD//wAAAqAEAAEAAAA8AAAAA6AEAAEAAAA8AAAAAAAAAA==", _t = "data:image/webp;base64,UklGRtgCAABXRUJQVlA4WAoAAAAIAAAAOwAAOwAAVlA4IPgBAABQCwCdASo8ADwAPm0wk0ekIqGhKBQMqIANiWkADPF3uV2D8VcQGk1mg+P36i9SLnZvYAQxszEWYzEwX1RVkqG/4BGbJgMSHqhKDFsjWsGfPPrvfef11goNmCDDlBJHVVD+8gAA/vu4q03kl+E7FpjtZ2gc8pQ619Hjv9NywoRZ6az43C1wcrRr/lWzJlJhLWMHN0MkVl1ueAf6Hn8StVzeUfMBXOKkgfe2msx7QWR5PnHW/5c6/35yrtWnrURc2q6UYlGin+v8C2dQqexkW6rX2EEijTI9eEQ46PWH3/59fM2AlMvvR2abaRk5XX7V1triQncRxvMfz5YmYDN+PY/ikcZUNaiFucKoUq5riv0eKCezuFNHecE11ojwJqWRSTWpalkz5autXp6vFS+FT1tWUsB/fs1CCOZxaA1vR1grOEaiuKe1RYm7e05psWtqbXLVmm1bA8Ly9PFkVdCbc6hR3UuBBsFGnVeGOUeMn2onnfvYhBMcM9YPxGdQkwZLXOk1VuQSTk01Shf3fZrFyRlFauftFdPYhKXwqrr+meav1P+KLKBVosqmHnFFfgExsQ/rOf3TSd+mOqQfJA+cF+HojNU7nmM3uDkoCBi+//Gqp+gPNNW8M4LFrol8rxE+7WsjqMgfwv1f+Nr25RtG1Wa/KkniRCAAAABFWElGugAAAEV4aWYAAElJKgAIAAAABgASAQMAAQAAAAEAAAAaAQUAAQAAAFYAAAAbAQUAAQAAAF4AAAAoAQMAAQAAAAIAAAATAgMAAQAAAAEAAABphwQAAQAAAGYAAAAAAAAASAAAAAEAAABIAAAAAQAAAAYAAJAHAAQAAAAwMjEwAZEHAAQAAAABAgMAAKAHAAQAAAAwMTAwAaADAAEAAAD//wAAAqAEAAEAAAA8AAAAA6AEAAEAAAA8AAAAAAAAAA==", Nt = {
|
|
2401
|
-
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: {
|
|
2402
|
-
symbol: "USDC",
|
|
2403
|
-
decimals: 6,
|
|
2404
|
-
icon: Ot
|
|
2405
|
-
},
|
|
2406
|
-
Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB: {
|
|
2407
|
-
symbol: "USDT",
|
|
2408
|
-
decimals: 6,
|
|
2409
|
-
icon: It
|
|
2410
|
-
},
|
|
2411
|
-
"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo": {
|
|
2412
|
-
symbol: "PYUSD",
|
|
2413
|
-
decimals: 6,
|
|
2414
|
-
icon: Bt
|
|
2415
|
-
},
|
|
2416
|
-
CASHx9KJUStyftLFWGvEVf59SGeG9sh5FfcnZMVPCASH: {
|
|
2417
|
-
symbol: "CASH",
|
|
2418
|
-
decimals: 6,
|
|
2419
|
-
icon: _t
|
|
2420
|
-
}
|
|
2421
|
-
}, oe = Object.fromEntries(
|
|
2422
|
-
Object.entries(Nt).map(([t, e]) => [t, e.symbol])
|
|
2423
|
-
);
|
|
2424
|
-
function Ft(t) {
|
|
2425
|
-
return t in oe;
|
|
2426
|
-
}
|
|
2427
|
-
function je(t, e = "token mint", r = !1) {
|
|
2428
|
-
if (!t || t.trim().length === 0)
|
|
2429
|
-
return {
|
|
2430
|
-
isValid: !0,
|
|
2431
|
-
isKnownStablecoin: !1
|
|
2432
|
-
};
|
|
2433
|
-
const a = t.trim();
|
|
2434
|
-
if (Ft(a))
|
|
2435
|
-
return {
|
|
2436
|
-
isValid: !0,
|
|
2437
|
-
isKnownStablecoin: !0,
|
|
2438
|
-
symbol: oe[a]
|
|
2439
|
-
};
|
|
2440
|
-
const n = Object.entries(oe).map(([i, o]) => ` ${o}: ${i}`).join(`
|
|
2441
|
-
`);
|
|
2442
|
-
return r ? {
|
|
2443
|
-
isValid: !0,
|
|
2444
|
-
// Allow but warn
|
|
2445
|
-
isKnownStablecoin: !1,
|
|
2446
|
-
warning: [
|
|
2447
|
-
`Warning: Unrecognized token mint address in ${e}`,
|
|
2448
|
-
` Provided: ${a}`,
|
|
2449
|
-
"",
|
|
2450
|
-
"This token mint does not match any known stablecoin addresses.",
|
|
2451
|
-
"You have set dangerouslyAllowUnknownMint=true, so this will proceed.",
|
|
2452
|
-
"If this is a typo, payments will be sent to the wrong token and funds will be PERMANENTLY LOST.",
|
|
2453
|
-
"",
|
|
2454
|
-
"Known stablecoin mints (mainnet-beta):",
|
|
2455
|
-
n,
|
|
2456
|
-
"",
|
|
2457
|
-
"Double-check your token mint address before deploying to production."
|
|
2458
|
-
].join(`
|
|
2459
|
-
`)
|
|
2460
|
-
} : {
|
|
2461
|
-
isValid: !1,
|
|
2462
|
-
isKnownStablecoin: !1,
|
|
2463
|
-
error: [
|
|
2464
|
-
`SAFETY ERROR: Unrecognized token mint address in ${e}`,
|
|
2465
|
-
` Provided: ${a}`,
|
|
2466
|
-
"",
|
|
2467
|
-
"This token mint does not match any known stablecoin addresses.",
|
|
2468
|
-
"Using an unknown token mint can result in PERMANENT LOSS OF FUNDS if it's a typo.",
|
|
2469
|
-
"",
|
|
2470
|
-
"Known stablecoin mints (mainnet-beta):",
|
|
2471
|
-
n,
|
|
2472
|
-
"",
|
|
2473
|
-
"If you are CERTAIN this is the correct mint address (custom token, testnet, or new stablecoin),",
|
|
2474
|
-
"set dangerouslyAllowUnknownMint={true} in your CedrosProvider config:",
|
|
2475
|
-
"",
|
|
2476
|
-
" <CedrosProvider",
|
|
2477
|
-
" config={{",
|
|
2478
|
-
" ...",
|
|
2479
|
-
' tokenMint: "' + a + '",',
|
|
2480
|
-
" dangerouslyAllowUnknownMint: true, // ⚠️ I have verified this mint address",
|
|
2481
|
-
" }}",
|
|
2482
|
-
" />",
|
|
2483
|
-
"",
|
|
2484
|
-
"⚠️ WARNING: Only enable dangerouslyAllowUnknownMint if you have TRIPLE-CHECKED the mint address."
|
|
2485
|
-
].join(`
|
|
2486
|
-
`)
|
|
2487
|
-
};
|
|
2488
|
-
}
|
|
2489
|
-
function $t(t, e = "unknown", r = !1) {
|
|
2490
|
-
return je(t, `X402Requirement (resource: ${e})`, r);
|
|
2491
|
-
}
|
|
2492
|
-
const be = /* @__PURE__ */ new Set(["mainnet-beta", "devnet", "testnet"]);
|
|
2493
|
-
function Ut() {
|
|
2494
|
-
if (typeof window < "u" && window.location)
|
|
2495
|
-
return window.location.origin;
|
|
2496
|
-
throw new Error(
|
|
2497
|
-
"serverUrl is required in SSR/Node environments. In browser environments, it defaults to window.location.origin"
|
|
2498
|
-
);
|
|
2499
|
-
}
|
|
2500
|
-
function Ht(t) {
|
|
2501
|
-
const e = [];
|
|
2502
|
-
if (t.showCard !== !1) {
|
|
2503
|
-
const n = t.stripePublicKey;
|
|
2504
|
-
(typeof n != "string" || n.trim().length === 0) && e.push({
|
|
2505
|
-
field: "stripePublicKey",
|
|
2506
|
-
message: "must be a non-empty string when card payments are enabled (showCard is not false)"
|
|
2507
|
-
});
|
|
2508
|
-
}
|
|
2509
|
-
let a;
|
|
2510
|
-
if (t.serverUrl !== void 0)
|
|
2511
|
-
typeof t.serverUrl != "string" || t.serverUrl.trim().length === 0 ? (e.push({
|
|
2512
|
-
field: "serverUrl",
|
|
2513
|
-
message: "must be a non-empty string when provided"
|
|
2514
|
-
}), a = "") : (!t.serverUrl.startsWith("http://") && !t.serverUrl.startsWith("https://") && e.push({
|
|
2515
|
-
field: "serverUrl",
|
|
2516
|
-
message: 'must start with "http://" or "https://"'
|
|
2517
|
-
}), a = t.serverUrl);
|
|
2518
|
-
else
|
|
2519
|
-
try {
|
|
2520
|
-
a = Ut();
|
|
2521
|
-
} catch (n) {
|
|
2522
|
-
e.push({
|
|
2523
|
-
field: "serverUrl",
|
|
2524
|
-
message: n instanceof Error ? n.message : "failed to determine default"
|
|
2525
|
-
}), a = "";
|
|
2526
|
-
}
|
|
2527
|
-
if (be.has(t.solanaCluster) || e.push({
|
|
2528
|
-
field: "solanaCluster",
|
|
2529
|
-
message: `must be one of ${Array.from(be).join(", ")}`
|
|
2530
|
-
}), t.solanaEndpoint !== void 0 && (typeof t.solanaEndpoint != "string" ? e.push({
|
|
2531
|
-
field: "solanaEndpoint",
|
|
2532
|
-
message: "must be a string when provided"
|
|
2533
|
-
}) : t.solanaEndpoint.trim().length === 0 ? e.push({
|
|
2534
|
-
field: "solanaEndpoint",
|
|
2535
|
-
message: 'must be a non-empty string when provided (e.g., "https://api.mainnet-beta.solana.com")'
|
|
2536
|
-
}) : !t.solanaEndpoint.startsWith("http://") && !t.solanaEndpoint.startsWith("https://") && e.push({
|
|
2537
|
-
field: "solanaEndpoint",
|
|
2538
|
-
message: 'must start with "http://" or "https://" (e.g., "https://api.mainnet-beta.solana.com")'
|
|
2539
|
-
})), t.tokenMint && typeof t.tokenMint != "string" && e.push({
|
|
2540
|
-
field: "tokenMint",
|
|
2541
|
-
message: "must be a string when provided"
|
|
2542
|
-
}), e.length > 0) {
|
|
2543
|
-
const n = e.map((i) => `- ${i.field} ${i.message}`).join(`
|
|
2544
|
-
`);
|
|
2545
|
-
throw new Error(`Invalid Cedros configuration:
|
|
2546
|
-
${n}`);
|
|
2547
|
-
}
|
|
2548
|
-
if (t.tokenMint) {
|
|
2549
|
-
const n = t.dangerouslyAllowUnknownMint === !0, i = je(t.tokenMint, "CedrosConfig.tokenMint", n);
|
|
2550
|
-
if (!i.isValid && i.error)
|
|
2551
|
-
throw new Error(i.error);
|
|
2552
|
-
i.warning && l().warn(i.warning);
|
|
2553
|
-
}
|
|
2554
|
-
return {
|
|
2555
|
-
...t,
|
|
2556
|
-
serverUrl: a
|
|
2557
|
-
};
|
|
2558
|
-
}
|
|
2559
|
-
const Lt = Object.freeze({
|
|
2560
|
-
surfaceBackground: "rgba(255, 255, 255, 0)",
|
|
2561
|
-
surfaceText: "#111827",
|
|
2562
|
-
surfaceBorder: "rgba(15, 23, 42, 0.08)",
|
|
2563
|
-
stripeBackground: "linear-gradient(135deg, #635bff 0%, #4f46e5 100%)",
|
|
2564
|
-
stripeText: "#ffffff",
|
|
2565
|
-
stripeShadow: "rgba(79, 70, 229, 0.25)",
|
|
2566
|
-
cryptoBackground: "linear-gradient(135deg, #14f195 0%, #9945ff 100%)",
|
|
2567
|
-
cryptoText: "#ffffff",
|
|
2568
|
-
cryptoShadow: "rgba(99, 102, 241, 0.25)",
|
|
2569
|
-
errorBackground: "#fee2e2",
|
|
2570
|
-
errorBorder: "#fca5a5",
|
|
2571
|
-
errorText: "#b91c1c",
|
|
2572
|
-
successBackground: "#dcfce7",
|
|
2573
|
-
successBorder: "#86efac",
|
|
2574
|
-
successText: "#166534",
|
|
2575
|
-
modalOverlay: "rgba(0, 0, 0, 0.5)",
|
|
2576
|
-
modalBackground: "#ffffff",
|
|
2577
|
-
modalBorder: "rgba(15, 23, 42, 0.08)",
|
|
2578
|
-
buttonBorderRadius: "8px",
|
|
2579
|
-
buttonPadding: "0.75rem 1.5rem",
|
|
2580
|
-
buttonFontSize: "1rem",
|
|
2581
|
-
buttonFontWeight: "600"
|
|
2582
|
-
}), qt = Object.freeze({
|
|
2583
|
-
surfaceBackground: "rgba(17, 24, 39, 0.6)",
|
|
2584
|
-
surfaceText: "#f9fafb",
|
|
2585
|
-
surfaceBorder: "rgba(148, 163, 184, 0.25)",
|
|
2586
|
-
stripeBackground: "linear-gradient(135deg, #4f46e5 0%, #3730a3 100%)",
|
|
2587
|
-
stripeText: "#f5f3ff",
|
|
2588
|
-
stripeShadow: "rgba(99, 102, 241, 0.35)",
|
|
2589
|
-
cryptoBackground: "linear-gradient(135deg, #1dd4a6 0%, #6d28d9 100%)",
|
|
2590
|
-
cryptoText: "#ecfeff",
|
|
2591
|
-
cryptoShadow: "rgba(75, 85, 99, 0.35)",
|
|
2592
|
-
errorBackground: "#7f1d1d",
|
|
2593
|
-
errorBorder: "#fca5a5",
|
|
2594
|
-
errorText: "#fecaca",
|
|
2595
|
-
successBackground: "#14532d",
|
|
2596
|
-
successBorder: "#4ade80",
|
|
2597
|
-
successText: "#bbf7d0",
|
|
2598
|
-
modalOverlay: "rgba(0, 0, 0, 0.75)",
|
|
2599
|
-
modalBackground: "#1f2937",
|
|
2600
|
-
modalBorder: "rgba(148, 163, 184, 0.25)",
|
|
2601
|
-
buttonBorderRadius: "8px",
|
|
2602
|
-
buttonPadding: "0.75rem 1.5rem",
|
|
2603
|
-
buttonFontSize: "1rem",
|
|
2604
|
-
buttonFontWeight: "600"
|
|
2605
|
-
}), jt = {
|
|
2606
|
-
surfaceBackground: "--cedros-surface-bg",
|
|
2607
|
-
surfaceText: "--cedros-surface-text",
|
|
2608
|
-
surfaceBorder: "--cedros-surface-border",
|
|
2609
|
-
stripeBackground: "--cedros-stripe-bg",
|
|
2610
|
-
stripeText: "--cedros-stripe-text",
|
|
2611
|
-
stripeShadow: "--cedros-stripe-shadow",
|
|
2612
|
-
cryptoBackground: "--cedros-crypto-bg",
|
|
2613
|
-
cryptoText: "--cedros-crypto-text",
|
|
2614
|
-
cryptoShadow: "--cedros-crypto-shadow",
|
|
2615
|
-
errorBackground: "--cedros-error-bg",
|
|
2616
|
-
errorBorder: "--cedros-error-border",
|
|
2617
|
-
errorText: "--cedros-error-text",
|
|
2618
|
-
successBackground: "--cedros-success-bg",
|
|
2619
|
-
successBorder: "--cedros-success-border",
|
|
2620
|
-
successText: "--cedros-success-text",
|
|
2621
|
-
modalOverlay: "--cedros-modal-overlay",
|
|
2622
|
-
modalBackground: "--cedros-modal-bg",
|
|
2623
|
-
modalBorder: "--cedros-modal-border",
|
|
2624
|
-
buttonBorderRadius: "--cedros-button-radius",
|
|
2625
|
-
buttonPadding: "--cedros-button-padding",
|
|
2626
|
-
buttonFontSize: "--cedros-button-font-size",
|
|
2627
|
-
buttonFontWeight: "--cedros-button-font-weight"
|
|
2628
|
-
}, ue = Ee(null);
|
|
2629
|
-
function zt(t, e) {
|
|
2630
|
-
return {
|
|
2631
|
-
...t === "dark" ? qt : Lt,
|
|
2632
|
-
...e
|
|
2633
|
-
};
|
|
2634
|
-
}
|
|
2635
|
-
function Qt(t) {
|
|
2636
|
-
const e = Object.entries(t).map(([r, a]) => [
|
|
2637
|
-
jt[r],
|
|
2638
|
-
a
|
|
2639
|
-
]);
|
|
2640
|
-
return Object.fromEntries(e);
|
|
2641
|
-
}
|
|
2642
|
-
function Wt({
|
|
2643
|
-
initialMode: t = "light",
|
|
2644
|
-
overrides: e,
|
|
2645
|
-
unstyled: r = !1,
|
|
2646
|
-
children: a
|
|
2647
|
-
}) {
|
|
2648
|
-
const [n, i] = U(t), [o, s] = U(e), c = ve(e);
|
|
2649
|
-
F(() => {
|
|
2650
|
-
if (e === c.current)
|
|
2651
|
-
return;
|
|
2652
|
-
(!e || !c.current ? e !== c.current : Object.keys({ ...e, ...c.current }).some(
|
|
2653
|
-
(h) => e[h] !== c.current?.[h]
|
|
2654
|
-
)) && (c.current = e, s(e));
|
|
2655
|
-
}, [e]);
|
|
2656
|
-
const u = ae(() => {
|
|
2657
|
-
const f = zt(n, o), h = r ? {} : Qt(f), y = r ? "" : `cedros-theme-root cedros-theme cedros-theme--${n}`;
|
|
2658
|
-
return {
|
|
2659
|
-
mode: n,
|
|
2660
|
-
setMode: i,
|
|
2661
|
-
tokens: f,
|
|
2662
|
-
className: y,
|
|
2663
|
-
style: h,
|
|
2664
|
-
unstyled: r
|
|
2665
|
-
};
|
|
2666
|
-
}, [n, o, r]);
|
|
2667
|
-
return /* @__PURE__ */ J(ue.Provider, { value: u, children: a });
|
|
2668
|
-
}
|
|
2669
|
-
function Xt() {
|
|
2670
|
-
const t = se(ue);
|
|
2671
|
-
if (!t)
|
|
2672
|
-
throw new Error("useCedrosTheme must be used within CedrosProvider");
|
|
2673
|
-
return t;
|
|
2674
|
-
}
|
|
2675
|
-
function Zt() {
|
|
2676
|
-
return se(ue);
|
|
2677
|
-
}
|
|
2678
|
-
const re = {
|
|
2679
|
-
getAdapters: () => [],
|
|
2680
|
-
cleanup: async () => {
|
|
2681
|
-
},
|
|
2682
|
-
isInitialized: () => !1,
|
|
2683
|
-
getId: () => "stub"
|
|
2684
|
-
};
|
|
2685
|
-
function Kt() {
|
|
2686
|
-
return typeof process < "u" && process.env.NODE_ENV === "development" ? 0 : 2;
|
|
2687
|
-
}
|
|
2688
|
-
const ze = Ee(null);
|
|
2689
|
-
function er({ config: t, children: e }) {
|
|
2690
|
-
const r = ae(() => Ht(t), [t]), [a, n] = U(null), [i, o] = U(re), s = ve(re);
|
|
2691
|
-
F(() => {
|
|
2692
|
-
let d = !1;
|
|
2693
|
-
return import("./walletPool-DE-t1wSW.mjs").then(({ createWalletPool: m }) => {
|
|
2694
|
-
if (d) return;
|
|
2695
|
-
const A = m();
|
|
2696
|
-
s.current = A, o(A);
|
|
2697
|
-
}).catch((m) => {
|
|
2698
|
-
d || (l().error("[CedrosProvider] Wallet pool initialization failed:", m), n("Failed to initialize Cedros provider"));
|
|
2699
|
-
}), () => {
|
|
2700
|
-
d = !0;
|
|
2701
|
-
};
|
|
2702
|
-
}, []);
|
|
2703
|
-
const [c, u] = U(null);
|
|
2704
|
-
F(() => {
|
|
2705
|
-
let d = !1;
|
|
2706
|
-
return import("./solanaCheck-IlYsbXDd.mjs").then(
|
|
2707
|
-
({ checkSolanaAvailability: m }) => m()
|
|
2708
|
-
).then((m) => {
|
|
2709
|
-
d || (m.available ? u(void 0) : u(m.error || "Solana dependencies not available"));
|
|
2710
|
-
}).catch((m) => {
|
|
2711
|
-
d || (l().warn("[CedrosProvider] Solana availability check failed:", m), u("Unable to verify Solana availability"));
|
|
2712
|
-
}), () => {
|
|
2713
|
-
d = !0;
|
|
2714
|
-
};
|
|
2715
|
-
}, []), F(() => {
|
|
2716
|
-
const d = r.logLevel ?? Kt(), m = et({
|
|
2717
|
-
level: d,
|
|
2718
|
-
prefix: "[CedrosPay]"
|
|
2719
|
-
});
|
|
2720
|
-
Ze(m);
|
|
2721
|
-
}, [r.logLevel]), F(() => () => {
|
|
2722
|
-
const d = s.current;
|
|
2723
|
-
d && d !== re && d.cleanup().catch((m) => {
|
|
2724
|
-
l().warn("[CedrosProvider] Wallet pool cleanup failed:", m);
|
|
2725
|
-
});
|
|
2726
|
-
}, []);
|
|
2727
|
-
const [f, h] = U(null);
|
|
2728
|
-
F(() => {
|
|
2729
|
-
let d = !1, m = !1;
|
|
2730
|
-
const A = r.stripePublicKey ?? "", b = r.serverUrl ?? "", x = r.solanaCluster, D = r.solanaEndpoint, M = r.dangerouslyAllowUnknownMint, S = r.complianceCheck;
|
|
2731
|
-
return Dt(A, b, x, D, M, S).then((_) => {
|
|
2732
|
-
if (d) {
|
|
2733
|
-
we(A, b, x, D, M, S);
|
|
2734
|
-
return;
|
|
2735
|
-
}
|
|
2736
|
-
m = !0, h(_);
|
|
2737
|
-
}).catch((_) => {
|
|
2738
|
-
d || (l().error("[CedrosProvider] Manager initialization failed:", _), n("Failed to initialize Cedros provider"));
|
|
2739
|
-
}), () => {
|
|
2740
|
-
d = !0, m && we(A, b, x, D, M, S);
|
|
2741
|
-
};
|
|
2742
|
-
}, [
|
|
2743
|
-
r.stripePublicKey,
|
|
2744
|
-
r.serverUrl,
|
|
2745
|
-
r.solanaCluster,
|
|
2746
|
-
r.solanaEndpoint,
|
|
2747
|
-
r.dangerouslyAllowUnknownMint,
|
|
2748
|
-
r.complianceCheck
|
|
2749
|
-
]);
|
|
2750
|
-
const y = ae(() => f ? {
|
|
2751
|
-
config: r,
|
|
2752
|
-
...f,
|
|
2753
|
-
walletPool: i,
|
|
2754
|
-
solanaError: c
|
|
2755
|
-
} : null, [r, f, i, c]);
|
|
2756
|
-
return a ? /* @__PURE__ */ J("div", { role: "alert", children: a }) : /* @__PURE__ */ J(
|
|
2757
|
-
Wt,
|
|
2758
|
-
{
|
|
2759
|
-
initialMode: r.theme ?? "light",
|
|
2760
|
-
overrides: r.themeOverrides,
|
|
2761
|
-
unstyled: r.unstyled ?? !1,
|
|
2762
|
-
children: y ? /* @__PURE__ */ J(ze.Provider, { value: y, children: e }) : null
|
|
2763
|
-
}
|
|
2764
|
-
);
|
|
2765
|
-
}
|
|
2766
|
-
function tr() {
|
|
2767
|
-
const t = se(ze);
|
|
2768
|
-
if (!t)
|
|
2769
|
-
throw new Error("useCedrosContext must be used within CedrosProvider");
|
|
2770
|
-
return t;
|
|
2771
|
-
}
|
|
2772
|
-
export {
|
|
2773
|
-
Yt as C,
|
|
2774
|
-
ot as E,
|
|
2775
|
-
oe as K,
|
|
2776
|
-
$e as L,
|
|
2777
|
-
N as P,
|
|
2778
|
-
B as R,
|
|
2779
|
-
Nt as S,
|
|
2780
|
-
er as a,
|
|
2781
|
-
g as b,
|
|
2782
|
-
at as c,
|
|
2783
|
-
xe as d,
|
|
2784
|
-
v as e,
|
|
2785
|
-
Q as f,
|
|
2786
|
-
et as g,
|
|
2787
|
-
I as h,
|
|
2788
|
-
l as i,
|
|
2789
|
-
Xt as j,
|
|
2790
|
-
$t as k,
|
|
2791
|
-
ge as l,
|
|
2792
|
-
O as m,
|
|
2793
|
-
je as n,
|
|
2794
|
-
it as o,
|
|
2795
|
-
p,
|
|
2796
|
-
Zt as q,
|
|
2797
|
-
E as r,
|
|
2798
|
-
w as s,
|
|
2799
|
-
tr as u,
|
|
2800
|
-
Ht as v
|
|
2801
|
-
};
|