@superlogic/spree-pay 0.1.42 → 0.2.1

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.
@@ -0,0 +1,838 @@
1
+ import {
2
+ CheckoutButton,
3
+ PointsSwitch,
4
+ cn as cn2
5
+ } from "./chunk-FGNS5H2Q.js";
6
+ import {
7
+ Dialog,
8
+ DialogContent,
9
+ DialogDescription,
10
+ DialogTitle,
11
+ InfoBanner,
12
+ PaymentError,
13
+ SlapiPaymentService,
14
+ cn,
15
+ logger,
16
+ useSpreePayConfig,
17
+ useSpreePayRegister,
18
+ useSpreePaymentMethod
19
+ } from "./chunk-RQX2IOTB.js";
20
+
21
+ // src/components/CryptoTab/Crypto/CryptoWrapper.tsx
22
+ import { useMemo as useMemo2 } from "react";
23
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
24
+ import NiceModal3 from "@ebay/nice-modal-react";
25
+ import { RainbowKitProvider, getDefaultConfig, lightTheme } from "@rainbow-me/rainbowkit";
26
+ import "@rainbow-me/rainbowkit/styles.css";
27
+ import { WagmiProvider } from "wagmi";
28
+ import { base } from "wagmi/chains";
29
+
30
+ // src/components/CryptoTab/Crypto/Crypto.tsx
31
+ import { useCallback, useEffect as useEffect2 } from "react";
32
+ import { useAccount as useAccount3 } from "wagmi";
33
+
34
+ // ../../node_modules/@wagmi/core/dist/esm/utils/getAction.js
35
+ function getAction(client, actionFn, name) {
36
+ const action_implicit = client[actionFn.name];
37
+ if (typeof action_implicit === "function")
38
+ return action_implicit;
39
+ const action_explicit = client[name];
40
+ if (typeof action_explicit === "function")
41
+ return action_explicit;
42
+ return (params) => actionFn(client, params);
43
+ }
44
+
45
+ // ../../node_modules/@wagmi/core/dist/esm/actions/readContract.js
46
+ import { readContract as viem_readContract } from "viem/actions";
47
+ function readContract(config, parameters) {
48
+ const { chainId, ...rest } = parameters;
49
+ const client = config.getClient({ chainId });
50
+ const action = getAction(client, viem_readContract, "readContract");
51
+ return action(rest);
52
+ }
53
+
54
+ // ../../node_modules/@wagmi/core/dist/esm/actions/waitForTransactionReceipt.js
55
+ import { hexToString } from "viem";
56
+ import { call, getTransaction, waitForTransactionReceipt as viem_waitForTransactionReceipt } from "viem/actions";
57
+ async function waitForTransactionReceipt(config, parameters) {
58
+ const { chainId, timeout = 0, ...rest } = parameters;
59
+ const client = config.getClient({ chainId });
60
+ const action = getAction(client, viem_waitForTransactionReceipt, "waitForTransactionReceipt");
61
+ const receipt = await action({ ...rest, timeout });
62
+ if (receipt.status === "reverted") {
63
+ const action_getTransaction = getAction(client, getTransaction, "getTransaction");
64
+ const { from: account, ...txn } = await action_getTransaction({
65
+ hash: receipt.transactionHash
66
+ });
67
+ const action_call = getAction(client, call, "call");
68
+ const code = await action_call({
69
+ ...txn,
70
+ account,
71
+ data: txn.input,
72
+ gasPrice: txn.type !== "eip1559" ? txn.gasPrice : void 0,
73
+ maxFeePerGas: txn.type === "eip1559" ? txn.maxFeePerGas : void 0,
74
+ maxPriorityFeePerGas: txn.type === "eip1559" ? txn.maxPriorityFeePerGas : void 0
75
+ });
76
+ const reason = code?.data ? hexToString(`0x${code.data.substring(138)}`) : "unknown reason";
77
+ throw new Error(reason);
78
+ }
79
+ return {
80
+ ...receipt,
81
+ chainId: client.chain.id
82
+ };
83
+ }
84
+
85
+ // ../../node_modules/@wagmi/core/dist/esm/exports/index.js
86
+ import { custom, http, webSocket } from "viem";
87
+
88
+ // src/hooks/payments/useCryptoPayment.ts
89
+ import { erc20Abi } from "viem";
90
+ import { useConfig, useWalletClient } from "wagmi";
91
+
92
+ // src/config/baseTokens.ts
93
+ var BASE_CHAIN_ID = 8453;
94
+ var BASE_TOKENS = [
95
+ {
96
+ address: "0x2b11834ed1feaed4b4b3a86a6f571315e25a884d",
97
+ chainId: BASE_CHAIN_ID,
98
+ decimals: 18,
99
+ symbol: "MOCA" /* MOCA */,
100
+ name: "Moca",
101
+ logoURI: "https://assets.coingecko.com/coins/images/30046/standard/moca.png"
102
+ },
103
+ {
104
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bDA02913",
105
+ chainId: BASE_CHAIN_ID,
106
+ decimals: 6,
107
+ symbol: "USDC" /* USDC */,
108
+ name: "USD Coin",
109
+ logoURI: "https://cryptologos.cc/logos/usd-coin-usdc-logo.png"
110
+ },
111
+ {
112
+ address: "0x4200000000000000000000000000000000000006",
113
+ chainId: BASE_CHAIN_ID,
114
+ decimals: 18,
115
+ symbol: "WETH" /* WETH */,
116
+ name: "Wrapped Ether",
117
+ logoURI: "https://static.cdnlogo.com/logos/e/84/ethereum-eth_thumb.png"
118
+ },
119
+ {
120
+ address: "0xfde4c96c8593536e31f229ea8f37b2ada2699bb2",
121
+ chainId: BASE_CHAIN_ID,
122
+ decimals: 6,
123
+ symbol: "USDT" /* USDT */,
124
+ name: "Tether USD",
125
+ logoURI: "https://cryptologos.cc/logos/tether-usdt-logo.png"
126
+ }
127
+ ];
128
+
129
+ // src/hooks/payments/useCryptoPayment.ts
130
+ var MAX_UINT256 = BigInt(2) ** BigInt(256) - BigInt(1);
131
+ var cryptoPaymentLogger = logger.child("crypto-payment");
132
+ var useCryptoPayment = () => {
133
+ const { data: walletClient } = useWalletClient();
134
+ const { spreePayConfig } = useSpreePayConfig();
135
+ const config = useConfig();
136
+ const { selectedPaymentMethod } = useSpreePaymentMethod();
137
+ const cryptoPayment = async (params) => {
138
+ if (!walletClient) {
139
+ const error = new Error("Wallet not connected");
140
+ cryptoPaymentLogger.error("Wallet not connected for crypto payment", error);
141
+ throw error;
142
+ }
143
+ if (!spreePayConfig) {
144
+ const error = new Error("Spree Pay config not loaded");
145
+ cryptoPaymentLogger.error("Config not loaded for crypto payment", error);
146
+ throw error;
147
+ }
148
+ if (selectedPaymentMethod.type !== "CRYPTO" /* CRYPTO */ || !selectedPaymentMethod.method?.symbol) {
149
+ const error = new Error("Unsupported payment method");
150
+ cryptoPaymentLogger.error("Invalid payment method for crypto payment", error, {
151
+ actualType: selectedPaymentMethod.type,
152
+ hasMethod: Boolean(selectedPaymentMethod.method)
153
+ });
154
+ throw error;
155
+ }
156
+ const { capture, hash, metadata } = params;
157
+ const TOKEN = selectedPaymentMethod.method.symbol;
158
+ cryptoPaymentLogger.info("Starting crypto payment", {
159
+ hash,
160
+ capture,
161
+ token: TOKEN,
162
+ walletAddress: walletClient.account.address
163
+ });
164
+ if (["MOCA" /* MOCA */, "WETH" /* WETH */, "USDC" /* USDC */, "USDT" /* USDT */].includes(TOKEN)) {
165
+ const tokenAddress = selectedPaymentMethod.method.address;
166
+ if (!tokenAddress) {
167
+ const error = new Error("Token address not found");
168
+ cryptoPaymentLogger.error("Token address missing", error, { token: TOKEN });
169
+ throw error;
170
+ }
171
+ cryptoPaymentLogger.debug("Checking token allowance", {
172
+ token: TOKEN,
173
+ tokenAddress,
174
+ router: spreePayConfig.crypto.oneInchAggregationRouter
175
+ });
176
+ const allowance = await readContract(config, {
177
+ address: tokenAddress,
178
+ abi: erc20Abi,
179
+ functionName: "allowance",
180
+ args: [walletClient.account.address, spreePayConfig.crypto.oneInchAggregationRouter]
181
+ });
182
+ if (allowance <= 0n) {
183
+ cryptoPaymentLogger.info("Requesting token approval", {
184
+ token: TOKEN,
185
+ tokenAddress
186
+ });
187
+ const result = await walletClient.writeContract({
188
+ address: tokenAddress,
189
+ abi: erc20Abi,
190
+ functionName: "approve",
191
+ args: [spreePayConfig.crypto.oneInchAggregationRouter, MAX_UINT256]
192
+ });
193
+ cryptoPaymentLogger.debug("Waiting for approval confirmation", {
194
+ approvalTxHash: result
195
+ });
196
+ await waitForTransactionReceipt(config, {
197
+ hash: result,
198
+ confirmations: 1
199
+ });
200
+ cryptoPaymentLogger.info("Token approval confirmed", {
201
+ approvalTxHash: result
202
+ });
203
+ } else {
204
+ cryptoPaymentLogger.debug("Sufficient allowance exists", {
205
+ allowance: allowance.toString()
206
+ });
207
+ }
208
+ }
209
+ cryptoPaymentLogger.debug("Creating crypto payment", {
210
+ token: TOKEN,
211
+ slippageBps: Math.round(0.5 * 100)
212
+ });
213
+ const paymentRes = await SlapiPaymentService.createPayment({
214
+ hash,
215
+ capture,
216
+ metadata,
217
+ type: "CRYPTO" /* CRYPTO */,
218
+ crypto: {
219
+ token: TOKEN,
220
+ publicKey: walletClient.account.address,
221
+ slippageType: "fixed",
222
+ slippageBps: Math.round(0.5 * 100)
223
+ }
224
+ });
225
+ cryptoPaymentLogger.info("Crypto payment created", {
226
+ paymentId: paymentRes.data.id,
227
+ txId: paymentRes.data.txId
228
+ });
229
+ const parsedTX = JSON.parse(paymentRes.data.encodedTx);
230
+ cryptoPaymentLogger.debug("Sending transaction", {
231
+ to: parsedTX.to,
232
+ value: parsedTX.value.toString()
233
+ });
234
+ const txHash = await walletClient.sendTransaction({
235
+ account: walletClient.account.address,
236
+ to: parsedTX.to,
237
+ data: parsedTX.data,
238
+ value: parsedTX.value
239
+ });
240
+ cryptoPaymentLogger.info("Transaction sent", {
241
+ txHash,
242
+ paymentId: paymentRes.data.id
243
+ });
244
+ cryptoPaymentLogger.debug("Verifying transaction on chain", {
245
+ txId: paymentRes.data.txId,
246
+ txHash
247
+ });
248
+ const res = await SlapiPaymentService.baseVerify({ id: paymentRes.data.txId, txHash });
249
+ const finalStatus = res.verified ? "CAPTURED" /* CAPTURED */ : "FAILED" /* FAILED */;
250
+ cryptoPaymentLogger.info("Crypto payment completed", {
251
+ paymentId: paymentRes.data.id,
252
+ txHash,
253
+ verified: res.verified,
254
+ status: finalStatus
255
+ });
256
+ return {
257
+ txHash,
258
+ paymentId: paymentRes.data.id,
259
+ txId: paymentRes.data.txId,
260
+ status: finalStatus,
261
+ paymentType: "CRYPTO" /* CRYPTO */
262
+ };
263
+ };
264
+ return { cryptoPayment };
265
+ };
266
+
267
+ // src/components/CryptoTab/Crypto/ConnectButton.tsx
268
+ import { ConnectButton as RainbowButton } from "@rainbow-me/rainbowkit";
269
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
270
+ var ConnectButton = () => {
271
+ const buttonCN = "h-9 rounded-full border border-(--b-brand) px-4 text-sm font-medium text-(--brand-primary)";
272
+ return /* @__PURE__ */ jsx(RainbowButton.Custom, { children: ({ mounted, chain, account, openAccountModal, openChainModal, openConnectModal }) => {
273
+ if (!mounted) return null;
274
+ return /* @__PURE__ */ jsx(Fragment, { children: (() => {
275
+ if (!mounted || !account || !chain) {
276
+ return /* @__PURE__ */ jsx("button", { className: buttonCN, onClick: openConnectModal, children: "Connect wallet" });
277
+ }
278
+ if (chain.unsupported) {
279
+ return /* @__PURE__ */ jsx("button", { className: buttonCN, onClick: openChainModal, children: "Select a Network" });
280
+ }
281
+ return /* @__PURE__ */ jsxs("button", { className: cn(buttonCN, "flex items-center gap-2 pl-1.5"), onClick: openAccountModal, children: [
282
+ chain.hasIcon && /* @__PURE__ */ jsx("div", { className: "size-6 overflow-hidden rounded-full", style: { background: chain.iconBackground }, children: chain.iconUrl && /* @__PURE__ */ jsx("img", { alt: chain.name ?? "Chain icon", src: chain.iconUrl }) }),
283
+ account.displayName
284
+ ] });
285
+ })() });
286
+ } });
287
+ };
288
+
289
+ // src/config/symbolLogos.tsx
290
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
291
+ var MOCA_SVG = /* @__PURE__ */ jsxs2("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", className: "size-7", viewBox: "0 0 28 28", children: [
292
+ /* @__PURE__ */ jsx2("circle", { cx: "14", cy: "14", r: "13.5", fill: "#c15f97" }),
293
+ /* @__PURE__ */ jsx2(
294
+ "path",
295
+ {
296
+ fill: "#fff",
297
+ d: "M16.06 6.65c.3 0 .59.16.74.43l6.06 10.5a.85.85 0 1 1-1.47.84L16.06 9.2l-1.51 2.62-.02.03-3.8 6.57a.85.85 0 0 1-1.47-.84l3.57-6.18-1.27-2.2-5.32 9.22a.85.85 0 0 1-1.48-.84l6.07-10.5.06-.1a.85.85 0 0 1 1.4.1l1.52 2.62 1.52-2.62.06-.1c.16-.2.4-.33.67-.33"
298
+ }
299
+ ),
300
+ /* @__PURE__ */ jsx2("circle", { cx: "16", cy: "14", r: "1.5", fill: "#fff" })
301
+ ] });
302
+ var USDC_SVG = /* @__PURE__ */ jsxs2("svg", { xmlns: "http://www.w3.org/2000/svg", className: "size-7", fill: "none", viewBox: "0 0 28 28", children: [
303
+ /* @__PURE__ */ jsx2("path", { fill: "#2775ca", d: "M14 28c7.76 0 14-6.24 14-14S21.76 0 14 0 0 6.24 0 14s6.24 14 14 14" }),
304
+ /* @__PURE__ */ jsx2(
305
+ "path",
306
+ {
307
+ fill: "#fff",
308
+ d: "M17.85 16.22c0-2.04-1.23-2.74-3.68-3.04-1.75-.23-2.1-.7-2.1-1.51 0-.82.59-1.34 1.75-1.34 1.05 0 1.64.35 1.93 1.22.06.18.23.3.4.3h.94a.4.4 0 0 0 .41-.42v-.05a2.91 2.91 0 0 0-2.63-2.4v-1.4c0-.23-.17-.4-.46-.46h-.88c-.23 0-.4.17-.46.46v1.35c-1.75.23-2.86 1.4-2.86 2.85 0 1.93 1.16 2.69 3.61 2.98 1.64.29 2.16.64 2.16 1.57 0 .94-.81 1.58-1.92 1.58-1.52 0-2.04-.64-2.22-1.52-.06-.23-.23-.35-.4-.35h-1a.4.4 0 0 0-.4.41v.06c.23 1.46 1.16 2.5 3.08 2.8v1.4c0 .23.18.4.47.47h.88c.23 0 .4-.18.46-.47v-1.4c1.75-.3 2.92-1.52 2.92-3.1Z"
309
+ }
310
+ ),
311
+ /* @__PURE__ */ jsx2(
312
+ "path",
313
+ {
314
+ fill: "#fff",
315
+ d: "M11.03 22.34a8.69 8.69 0 0 1-5.2-11.2 8.63 8.63 0 0 1 5.2-5.19.6.6 0 0 0 .35-.58v-.82c0-.23-.12-.4-.35-.47-.06 0-.18 0-.24.06a10.48 10.48 0 0 0 0 20.01c.24.12.47 0 .53-.23.06-.06.06-.12.06-.24v-.81c0-.18-.18-.41-.35-.53m6.18-18.2c-.23-.12-.47 0-.53.23-.05.06-.05.12-.05.24v.81c0 .24.17.47.35.59a8.69 8.69 0 0 1 5.19 11.2 8.63 8.63 0 0 1-5.2 5.19c-.23.12-.34.3-.34.58v.82c0 .23.11.4.35.47.05 0 .17 0 .23-.06a10.48 10.48 0 0 0 6.82-13.19 10.58 10.58 0 0 0-6.82-6.88"
316
+ }
317
+ )
318
+ ] });
319
+ var USDT_SVG = /* @__PURE__ */ jsxs2("svg", { xmlns: "http://www.w3.org/2000/svg", className: "size-7", fill: "none", viewBox: "0 0 28 28", children: [
320
+ /* @__PURE__ */ jsx2("path", { fill: "#26a17b", d: "M14 28a14 14 0 1 0 0-28 14 14 0 0 0 0 28" }),
321
+ /* @__PURE__ */ jsx2(
322
+ "path",
323
+ {
324
+ fill: "#fff",
325
+ d: "M15.5 15.3v-.01c-.1 0-.6.04-1.72.04-.88 0-1.5-.03-1.73-.04-3.42-.15-5.97-.74-5.97-1.46 0-.7 2.55-1.3 5.97-1.46v2.33a26 26 0 0 0 3.44 0v-2.32c3.42.15 5.96.74 5.96 1.46 0 .7-2.55 1.3-5.96 1.45m0-3.15v-2.08h4.76V6.89H7.3v3.17h4.76v2.08c-3.87.17-6.77.94-6.77 1.86s2.9 1.68 6.77 1.86v6.67h3.45v-6.67c3.86-.18 6.76-.94 6.76-1.86s-2.9-1.68-6.76-1.86"
326
+ }
327
+ )
328
+ ] });
329
+ var WETH_SVG = /* @__PURE__ */ jsxs2("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", className: "size-7", viewBox: "0 0 24 24", children: [
330
+ /* @__PURE__ */ jsxs2("g", { clipPath: "url(#clip0_528_9173)", children: [
331
+ /* @__PURE__ */ jsx2(
332
+ "path",
333
+ {
334
+ fill: "#000",
335
+ d: "M17.14 20.57c0 .95-1.31 2.01-3.39 2.4h-2.59c-4.65 0-8.42-1.07-8.42-2.4 0-1.32 3.77-2.4 8.42-2.4s5.98 1.08 5.98 2.4Z"
336
+ }
337
+ ),
338
+ /* @__PURE__ */ jsx2(
339
+ "path",
340
+ {
341
+ fill: "#F61F7D",
342
+ d: "M23.31 11c0 5.86-5.18 11.63-11.07 11.63-5.9 0-11.9-6.17-11.9-12.03C.34 4.75 5.12 0 11.01 0s12.3 5.15 12.3 11Z"
343
+ }
344
+ ),
345
+ /* @__PURE__ */ jsx2(
346
+ "path",
347
+ {
348
+ fill: "#000",
349
+ fillRule: "evenodd",
350
+ d: "M19.19 18.27c1.87-2 3.03-4.65 3.03-7.26 0-2.52-1.39-5-3.56-6.87-2.18-1.88-5-3.05-7.65-3.05a9.54 9.54 0 0 0-9.57 9.51c0 2.57 1.33 5.31 3.42 7.44 2.1 2.13 4.8 3.5 7.38 3.5a9.7 9.7 0 0 0 6.95-3.27Zm-6.95 4.36c5.89 0 11.07-5.77 11.07-11.62C23.31 5.15 16.9 0 11.01 0A10.63 10.63 0 0 0 .34 10.6c0 5.86 6 12.03 11.9 12.03Z",
351
+ clipRule: "evenodd"
352
+ }
353
+ ),
354
+ /* @__PURE__ */ jsx2("path", { fill: "#fff", d: "M24 12.17a10.8 10.8 0 1 1-21.6 0 10.8 10.8 0 0 1 21.6 0Z" }),
355
+ /* @__PURE__ */ jsx2(
356
+ "path",
357
+ {
358
+ fill: "#000",
359
+ fillRule: "evenodd",
360
+ d: "M13.2 21.87a9.7 9.7 0 1 0 0-19.4 9.7 9.7 0 0 0 0 19.4Zm0 1.1a10.8 10.8 0 1 0 0-21.6 10.8 10.8 0 0 0 0 21.6Z",
361
+ clipRule: "evenodd"
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsx2("path", { fill: "#000", fillRule: "evenodd", d: "M3.02 10.63.7 8.75l.74-.86 2.34 1.87-.75.87Z", clipRule: "evenodd" }),
365
+ /* @__PURE__ */ jsx2(
366
+ "path",
367
+ {
368
+ fill: "#000",
369
+ d: "M5.83 9.94h.99l.31 3 .4-3h.78l.41 2.98.32-2.98h.98l-.63 5.15H8.37l-.45-3.1-.42 3.1H6.47l-.64-5.15ZM10.91 9.94h2.38v.78h-1.2v1.27H13v.8h-.92v1.53h1.22v.77h-2.39V9.94ZM14.64 10.79h-.81v-.85h2.78v.85h-.8v4.3h-1.17v-4.3ZM17.42 9.94h1.16v2.09h.82V9.94h1.17v5.15H19.4v-2.25h-.82v2.25h-1.16V9.94Z"
370
+ }
371
+ )
372
+ ] }),
373
+ /* @__PURE__ */ jsx2("defs", { children: /* @__PURE__ */ jsx2("clipPath", { id: "clip0_528_9173", children: /* @__PURE__ */ jsx2("path", { fill: "#fff", d: "M0 0h24v24H0z" }) }) })
374
+ ] });
375
+ var symbolLogos = {
376
+ MOCA: MOCA_SVG,
377
+ USDC: USDC_SVG,
378
+ USDT: USDT_SVG,
379
+ WETH: WETH_SVG
380
+ };
381
+ function getSymbolLogo(symbol) {
382
+ return symbolLogos[symbol] ?? null;
383
+ }
384
+
385
+ // src/components/CryptoTab/Crypto/Logos.tsx
386
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
387
+ var Logos = () => {
388
+ return /* @__PURE__ */ jsxs3("div", { className: "flex", children: [
389
+ /* @__PURE__ */ jsx3("div", { className: "rounded-full border border-(--b-primary)", children: getSymbolLogo("MOCA") }),
390
+ /* @__PURE__ */ jsx3("div", { className: "-ml-2.5 rounded-full border border-(--b-primary)", children: getSymbolLogo("USDC") }),
391
+ /* @__PURE__ */ jsx3("div", { className: "-ml-2.5 rounded-full border border-(--b-primary)", children: getSymbolLogo("USDT") }),
392
+ /* @__PURE__ */ jsx3("div", { className: "-ml-2.5 rounded-full border border-(--b-primary) bg-(--s-primary)", children: getSymbolLogo("WETH") })
393
+ ] });
394
+ };
395
+
396
+ // src/components/CryptoTab/Crypto/SelectCoinButton.tsx
397
+ import NiceModal2 from "@ebay/nice-modal-react";
398
+
399
+ // src/modals/CryptoSelectModal.tsx
400
+ import { useMemo, useState as useState2 } from "react";
401
+ import NiceModal, { useModal } from "@ebay/nice-modal-react";
402
+
403
+ // ../ui/src/components/input.tsx
404
+ import { jsx as jsx4 } from "react/jsx-runtime";
405
+ function Input({ className, type, ...props }) {
406
+ return /* @__PURE__ */ jsx4(
407
+ "input",
408
+ {
409
+ type,
410
+ "data-slot": "input",
411
+ className: cn2(
412
+ "file:text-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base text-(--primary) shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-(--tertiary) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
413
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
414
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
415
+ className
416
+ ),
417
+ ...props
418
+ }
419
+ );
420
+ }
421
+
422
+ // ../../node_modules/@radix-ui/react-separator/dist/index.mjs
423
+ import * as React2 from "react";
424
+
425
+ // ../../node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.mjs
426
+ import * as React from "react";
427
+ import * as ReactDOM from "react-dom";
428
+ import { createSlot } from "@radix-ui/react-slot";
429
+ import { jsx as jsx5 } from "react/jsx-runtime";
430
+ var NODES = [
431
+ "a",
432
+ "button",
433
+ "div",
434
+ "form",
435
+ "h2",
436
+ "h3",
437
+ "img",
438
+ "input",
439
+ "label",
440
+ "li",
441
+ "nav",
442
+ "ol",
443
+ "p",
444
+ "select",
445
+ "span",
446
+ "svg",
447
+ "ul"
448
+ ];
449
+ var Primitive = NODES.reduce((primitive, node) => {
450
+ const Slot = createSlot(`Primitive.${node}`);
451
+ const Node = React.forwardRef((props, forwardedRef) => {
452
+ const { asChild, ...primitiveProps } = props;
453
+ const Comp = asChild ? Slot : node;
454
+ if (typeof window !== "undefined") {
455
+ window[/* @__PURE__ */ Symbol.for("radix-ui")] = true;
456
+ }
457
+ return /* @__PURE__ */ jsx5(Comp, { ...primitiveProps, ref: forwardedRef });
458
+ });
459
+ Node.displayName = `Primitive.${node}`;
460
+ return { ...primitive, [node]: Node };
461
+ }, {});
462
+
463
+ // ../../node_modules/@radix-ui/react-separator/dist/index.mjs
464
+ import { jsx as jsx6 } from "react/jsx-runtime";
465
+ var NAME = "Separator";
466
+ var DEFAULT_ORIENTATION = "horizontal";
467
+ var ORIENTATIONS = ["horizontal", "vertical"];
468
+ var Separator = React2.forwardRef((props, forwardedRef) => {
469
+ const { decorative, orientation: orientationProp = DEFAULT_ORIENTATION, ...domProps } = props;
470
+ const orientation = isValidOrientation(orientationProp) ? orientationProp : DEFAULT_ORIENTATION;
471
+ const ariaOrientation = orientation === "vertical" ? orientation : void 0;
472
+ const semanticProps = decorative ? { role: "none" } : { "aria-orientation": ariaOrientation, role: "separator" };
473
+ return /* @__PURE__ */ jsx6(
474
+ Primitive.div,
475
+ {
476
+ "data-orientation": orientation,
477
+ ...semanticProps,
478
+ ...domProps,
479
+ ref: forwardedRef
480
+ }
481
+ );
482
+ });
483
+ Separator.displayName = NAME;
484
+ function isValidOrientation(orientation) {
485
+ return ORIENTATIONS.includes(orientation);
486
+ }
487
+ var Root = Separator;
488
+
489
+ // ../ui/src/components/separator.tsx
490
+ import { jsx as jsx7 } from "react/jsx-runtime";
491
+ function Separator2({
492
+ className,
493
+ orientation = "horizontal",
494
+ decorative = true,
495
+ ...props
496
+ }) {
497
+ return /* @__PURE__ */ jsx7(
498
+ Root,
499
+ {
500
+ "data-slot": "separator",
501
+ decorative,
502
+ orientation,
503
+ className: cn2(
504
+ "shrink-0 bg-(--b-secondary) data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
505
+ className
506
+ ),
507
+ ...props
508
+ }
509
+ );
510
+ }
511
+
512
+ // src/hooks/useBaseERC20Token.ts
513
+ import * as React3 from "react";
514
+ import { erc20Abi as erc20Abi2, formatUnits, getAddress } from "viem";
515
+ import { useAccount, usePublicClient } from "wagmi";
516
+ function useBaseERC20Token() {
517
+ const { address } = useAccount();
518
+ const baseClient = usePublicClient({ chainId: BASE_CHAIN_ID });
519
+ const defaultClient = usePublicClient();
520
+ const [rows, setRows] = React3.useState([]);
521
+ const [isLoading, setLoading] = React3.useState(false);
522
+ const [error, setError] = React3.useState(null);
523
+ React3.useEffect(() => {
524
+ let cancelled = false;
525
+ async function run() {
526
+ const client = baseClient ?? defaultClient;
527
+ if (!address || !client) {
528
+ setRows([]);
529
+ return;
530
+ }
531
+ setLoading(true);
532
+ try {
533
+ const normalizedTokens = [];
534
+ for (const t of BASE_TOKENS) {
535
+ try {
536
+ const addr = getAddress(t.address);
537
+ normalizedTokens.push({ ...t, address: addr });
538
+ } catch {
539
+ }
540
+ }
541
+ const res = await client.multicall({
542
+ allowFailure: true,
543
+ contracts: normalizedTokens.map((t) => ({
544
+ address: t.address,
545
+ abi: erc20Abi2,
546
+ functionName: "balanceOf",
547
+ args: [address]
548
+ }))
549
+ });
550
+ const acc = [];
551
+ for (let idx = 0; idx < res.length; idx++) {
552
+ const r = res[idx];
553
+ const t = normalizedTokens[idx];
554
+ if (r.status === "success") {
555
+ const raw = r.result;
556
+ if (raw > 0n) acc.push({ ...t, raw, formatted: formatUnits(raw, t.decimals) });
557
+ }
558
+ }
559
+ if (!cancelled) setRows(acc);
560
+ } catch (e) {
561
+ if (!cancelled) {
562
+ const msg = e instanceof Error ? e.message : "Multicall failed";
563
+ setError(
564
+ baseClient ? msg : `Base client unavailable. Ensure Base (${BASE_CHAIN_ID}) is configured in Wagmi.`
565
+ );
566
+ }
567
+ } finally {
568
+ if (!cancelled) setLoading(false);
569
+ }
570
+ }
571
+ run();
572
+ return () => {
573
+ cancelled = true;
574
+ };
575
+ }, [address, baseClient, defaultClient]);
576
+ return { isLoading, error: error ?? null, erc20Balances: rows };
577
+ }
578
+
579
+ // src/hooks/useBaseNativeToken.ts
580
+ import { useAccount as useAccount2, useBalance } from "wagmi";
581
+ function useBaseNativeToken() {
582
+ const { address } = useAccount2();
583
+ const { data, isLoading, error } = useBalance({
584
+ address,
585
+ chainId: BASE_CHAIN_ID,
586
+ query: { enabled: !!address }
587
+ });
588
+ const nativeBalance = data ? { ...data, symbol: "ETH" /* ETH */, logoURI: "https://static.cdnlogo.com/logos/e/84/ethereum-eth_thumb.png" } : void 0;
589
+ return {
590
+ isLoadingNative: isLoading,
591
+ nativeError: error?.message ?? null,
592
+ nativeBalance
593
+ };
594
+ }
595
+
596
+ // src/hooks/useBaseTokens.ts
597
+ import useSWR from "swr";
598
+ var useBaseTokens = () => {
599
+ const { data: resData, isLoading } = useSWR(`/v1/base-transactions/tokens`);
600
+ return { tokens: resData?.data ?? [], tokensIsLoading: isLoading };
601
+ };
602
+
603
+ // src/modals/CryptoSelectModal.tsx
604
+ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
605
+ var CryptoSelectModal = NiceModal.create(() => {
606
+ const modal = useModal();
607
+ const { isLoading, error, erc20Balances } = useBaseERC20Token();
608
+ const { isLoadingNative, nativeError, nativeBalance } = useBaseNativeToken();
609
+ const { tokens, tokensIsLoading } = useBaseTokens();
610
+ const [search, setSearch] = useState2("");
611
+ const filteredCoins = useMemo(() => {
612
+ return tokens.filter(
613
+ (coin) => coin.name.toLowerCase().includes(search.toLowerCase()) || coin.symbol.toLowerCase().includes(search.toLowerCase())
614
+ );
615
+ }, [tokens, search]);
616
+ const { setSelectedPaymentMethod } = useSpreePaymentMethod();
617
+ const handleSelect = (coin) => {
618
+ modal.remove();
619
+ setSelectedPaymentMethod({ type: "CRYPTO" /* CRYPTO */, method: coin });
620
+ };
621
+ const userCoins = [nativeBalance, ...erc20Balances].filter(Boolean);
622
+ return /* @__PURE__ */ jsxs4(Dialog, { open: modal.visible, onOpenChange: modal.remove, children: [
623
+ /* @__PURE__ */ jsx8(DialogDescription, { className: "hidden", children: "Crypto Select Modal" }),
624
+ /* @__PURE__ */ jsxs4(DialogContent, { showCloseButton: false, className: "max-h-[90vh] gap-0 p-0", children: [
625
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-4 px-5 py-5 md:px-7", children: [
626
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-4", children: [
627
+ /* @__PURE__ */ jsx8("button", { className: "rounded-md hover:bg-(--s-primary-hover)", onClick: modal.remove, children: /* @__PURE__ */ jsx8("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", className: "size-6", viewBox: "0 0 24 25", children: /* @__PURE__ */ jsx8("path", { stroke: "currentColor", d: "m15 6.5-6 6 6 6" }) }) }),
628
+ /* @__PURE__ */ jsx8(DialogTitle, { className: "text-2xl font-medium text-(--brand-primary)", children: "Select a token" }),
629
+ /* @__PURE__ */ jsx8("button", { className: "rounded-md p-1 hover:bg-(--s-primary-hover)", onClick: modal.remove, children: /* @__PURE__ */ jsx8("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", className: "size-4", viewBox: "0 0 16 17", children: /* @__PURE__ */ jsx8(
630
+ "path",
631
+ {
632
+ fill: "currentColor",
633
+ d: "M12.6 3.9c.2.2.2.52 0 .71L8.7 8.5l3.9 3.89a.5.5 0 1 1-.71.7L8 9.22 4.11 13.1a.5.5 0 1 1-.7-.71L7.28 8.5 3.4 4.61a.5.5 0 1 1 .71-.7L8 7.78l3.89-3.89c.2-.2.51-.2.7 0Z"
634
+ }
635
+ ) }) })
636
+ ] }),
637
+ /* @__PURE__ */ jsx8(Input, { onChange: (e) => setSearch(e.target.value), placeholder: "Search by token name", value: search })
638
+ ] }),
639
+ /* @__PURE__ */ jsx8(Separator2, { className: "hidden md:block" }),
640
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-4 px-5 py-5 md:px-7", children: [
641
+ /* @__PURE__ */ jsx8("h3", { className: "text-md font-medium text-(--brand-primary)", children: "Tokens with wallet balance" }),
642
+ (error || nativeError) && /* @__PURE__ */ jsx8("p", { className: "text-center text-sm text-(--negative)", children: "Something wrong" }),
643
+ /* @__PURE__ */ jsxs4("div", { className: "flex w-full flex-col gap-1", children: [
644
+ isLoadingNative && /* @__PURE__ */ jsx8("div", { className: "h-11 animate-pulse rounded-md bg-(--s-primary)" }),
645
+ nativeBalance && /* @__PURE__ */ jsxs4(
646
+ "button",
647
+ {
648
+ className: "flex h-11 w-full items-center justify-between gap-4 rounded-sm px-1.5 text-(--brand-primary) hover:bg-(--s-primary-hover)",
649
+ onClick: () => handleSelect(nativeBalance),
650
+ children: [
651
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
652
+ nativeBalance.logoURI && /* @__PURE__ */ jsx8("img", { className: "size-8 shrink-0", src: nativeBalance.logoURI, alt: `${nativeBalance.symbol} logo` }),
653
+ /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium", children: nativeBalance.symbol })
654
+ ] }),
655
+ /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium", children: nativeBalance.formatted })
656
+ ]
657
+ },
658
+ nativeBalance.symbol
659
+ ),
660
+ isLoading && /* @__PURE__ */ jsxs4(Fragment2, { children: [
661
+ /* @__PURE__ */ jsx8("div", { className: "h-11 animate-pulse rounded-md bg-(--s-primary)" }),
662
+ /* @__PURE__ */ jsx8("div", { className: "h-11 animate-pulse rounded-md bg-(--s-primary)" }),
663
+ /* @__PURE__ */ jsx8("div", { className: "h-11 animate-pulse rounded-md bg-(--s-primary)" })
664
+ ] }),
665
+ erc20Balances.map((coin) => {
666
+ const Icon = getSymbolLogo(coin.symbol);
667
+ return /* @__PURE__ */ jsxs4(
668
+ "button",
669
+ {
670
+ className: "flex h-11 w-full items-center justify-between gap-4 rounded-sm px-1.5 text-(--brand-primary) hover:bg-(--s-primary-hover) disabled:cursor-not-allowed disabled:opacity-50",
671
+ onClick: () => handleSelect(coin),
672
+ children: [
673
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
674
+ Boolean(Icon) && Icon,
675
+ /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium", children: coin.symbol })
676
+ ] }),
677
+ /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium", children: coin.formatted })
678
+ ]
679
+ },
680
+ coin.symbol
681
+ );
682
+ })
683
+ ] }),
684
+ /* @__PURE__ */ jsx8("h3", { className: "text-md font-medium text-(--brand-primary)", children: "All Tokens" }),
685
+ /* @__PURE__ */ jsxs4("div", { className: "flex max-h-[40vh] w-full flex-col gap-1 overflow-y-auto", children: [
686
+ tokensIsLoading && /* @__PURE__ */ jsxs4(Fragment2, { children: [
687
+ /* @__PURE__ */ jsx8("div", { className: "h-11 animate-pulse rounded-md bg-(--s-primary)" }),
688
+ /* @__PURE__ */ jsx8("div", { className: "h-11 animate-pulse rounded-md bg-(--s-primary)" }),
689
+ /* @__PURE__ */ jsx8("div", { className: "h-11 animate-pulse rounded-md bg-(--s-primary)" })
690
+ ] }),
691
+ filteredCoins.map((token) => {
692
+ const userCoin = userCoins.find((c) => c.symbol === token.symbol);
693
+ return /* @__PURE__ */ jsx8(
694
+ "button",
695
+ {
696
+ disabled: !userCoin,
697
+ onClick: () => userCoin && handleSelect(userCoin),
698
+ className: "flex min-h-11 w-full items-center justify-between gap-4 rounded-sm px-1.5 text-(--brand-primary) hover:bg-(--s-primary-hover) disabled:cursor-not-allowed disabled:opacity-50",
699
+ children: /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
700
+ token.logoURI ? /* @__PURE__ */ jsx8("img", { className: "size-8 shrink-0", src: token.logoURI, alt: `${token.name} logo` }) : /* @__PURE__ */ jsx8("div", { className: "size-8 shrink-0 rounded-full bg-(--s-tertiary)" }),
701
+ /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium", children: token.symbol })
702
+ ] })
703
+ },
704
+ token.symbol
705
+ );
706
+ })
707
+ ] })
708
+ ] })
709
+ ] })
710
+ ] });
711
+ });
712
+ CryptoSelectModal.displayName = "CryptoSelectModal";
713
+
714
+ // src/components/CryptoTab/Crypto/SelectCoinButton.tsx
715
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
716
+ var SelectCoinButton = () => {
717
+ const openModal = () => {
718
+ NiceModal2.show(CryptoSelectModal);
719
+ };
720
+ return /* @__PURE__ */ jsx9(
721
+ "button",
722
+ {
723
+ onClick: openModal,
724
+ className: "flex h-11 w-full overflow-hidden rounded-md bg-(--s-primary) hover:bg-(--s-primary-hover)",
725
+ children: /* @__PURE__ */ jsxs5("div", { className: "flex h-full w-full items-center justify-between px-3", children: [
726
+ /* @__PURE__ */ jsx9("div", { className: "flex items-center", children: /* @__PURE__ */ jsx9("p", { className: "font-medium text-(--secondary)", children: "Select a token" }) }),
727
+ /* @__PURE__ */ jsx9("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", className: "size-4", viewBox: "0 0 16 16", children: /* @__PURE__ */ jsx9("path", { stroke: "currentColor", d: "m6 12.43 4-4-4-4" }) })
728
+ ] })
729
+ }
730
+ );
731
+ };
732
+
733
+ // src/components/CryptoTab/Crypto/SelectedCoin.tsx
734
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
735
+ var SelectedCoin = (props) => {
736
+ const { coin, balance, logoURI } = props;
737
+ const Icon = getSymbolLogo(coin);
738
+ return /* @__PURE__ */ jsxs6("div", { className: "flex h-12 w-full overflow-hidden rounded-md border-2 border-(--b-brand) bg-(--s-primary)", children: [
739
+ /* @__PURE__ */ jsx10("div", { className: "flex h-full w-11 shrink-0 items-center justify-center border-r border-(--b-brand) bg-(--s-primary)", children: /* @__PURE__ */ jsx10("div", { className: "flex size-5 items-center justify-center rounded-full border-2 border-(--brand-primary)", children: /* @__PURE__ */ jsx10("div", { className: "size-2 rounded-full bg-(--brand-primary)" }) }) }),
740
+ /* @__PURE__ */ jsxs6("div", { className: "flex h-full w-full items-center justify-between rounded-r-md px-3", children: [
741
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
742
+ Icon,
743
+ !Icon && logoURI && /* @__PURE__ */ jsx10("img", { className: "mr-1 size-8 shrink-0", src: logoURI, alt: `${coin} logo` }),
744
+ /* @__PURE__ */ jsx10("p", { className: "font-semibold text-(--brand-primary)", children: coin }),
745
+ /* @__PURE__ */ jsx10("svg", { xmlns: "http://www.w3.org/2000/svg", className: "size-4", fill: "none", viewBox: "0 0 16 16", children: /* @__PURE__ */ jsx10("path", { stroke: "currentColor", d: "m6 12.434 4-4-4-4" }) })
746
+ ] }),
747
+ /* @__PURE__ */ jsxs6("p", { className: "text-xs font-medium text-(--secondary)", children: [
748
+ "Wallet balance ",
749
+ /* @__PURE__ */ jsx10("span", { className: "text-(--brand-primary)", children: balance })
750
+ ] })
751
+ ] })
752
+ ] });
753
+ };
754
+
755
+ // src/components/CryptoTab/Crypto/Crypto.tsx
756
+ import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
757
+ var Crypto = () => {
758
+ const { address } = useAccount3();
759
+ const { selectedPaymentMethod } = useSpreePaymentMethod();
760
+ const { cryptoPayment } = useCryptoPayment();
761
+ const { spreePayConfig } = useSpreePayConfig();
762
+ const isWalletConnected = Boolean(address);
763
+ const { register } = useSpreePayRegister();
764
+ const handlePay = useCallback(
765
+ async (data) => {
766
+ try {
767
+ const res = await cryptoPayment(data);
768
+ if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
769
+ return Promise.resolve(res);
770
+ }
771
+ return Promise.reject(new PaymentError("Crypto payment failed", res.status));
772
+ } catch (_) {
773
+ return Promise.reject(new PaymentError("Payment failed", "FAILED" /* FAILED */));
774
+ }
775
+ },
776
+ [cryptoPayment]
777
+ );
778
+ useEffect2(() => {
779
+ register(handlePay);
780
+ }, [register, handlePay]);
781
+ return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-baseline gap-4", children: [
782
+ /* @__PURE__ */ jsxs7("div", { className: "flex w-full items-center justify-between gap-4", children: [
783
+ /* @__PURE__ */ jsx11("h3", { className: "text-lg leading-7 font-medium text-(--brand-primary) md:text-[22px]", children: "Pay with Crypto" }),
784
+ /* @__PURE__ */ jsx11(ConnectButton, {})
785
+ ] }),
786
+ !isWalletConnected && /* @__PURE__ */ jsx11(Logos, {}),
787
+ isWalletConnected && /* @__PURE__ */ jsxs7("div", { className: "flex w-full flex-col gap-4", children: [
788
+ selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && selectedPaymentMethod.method && /* @__PURE__ */ jsx11(
789
+ SelectedCoin,
790
+ {
791
+ coin: selectedPaymentMethod.method.symbol,
792
+ balance: selectedPaymentMethod.method.formatted,
793
+ logoURI: selectedPaymentMethod.method.logoURI
794
+ }
795
+ ),
796
+ /* @__PURE__ */ jsx11(SelectCoinButton, {})
797
+ ] }),
798
+ spreePayConfig?.crypto.infoMessage && /* @__PURE__ */ jsx11(InfoBanner, { message: spreePayConfig.crypto.infoMessage })
799
+ ] });
800
+ };
801
+
802
+ // src/components/CryptoTab/Crypto/CryptoWrapper.tsx
803
+ import { jsx as jsx12 } from "react/jsx-runtime";
804
+ var queryClient = new QueryClient();
805
+ var CHAINS = [base];
806
+ var wagmiConfigCache = /* @__PURE__ */ new Map();
807
+ function getCachedWagmiConfig(projectId, appName) {
808
+ const key = `${projectId}::${appName}`;
809
+ let cfg = wagmiConfigCache.get(key);
810
+ if (!cfg) {
811
+ cfg = getDefaultConfig({ appName, projectId, chains: CHAINS, ssr: true });
812
+ wagmiConfigCache.set(key, cfg);
813
+ }
814
+ return cfg;
815
+ }
816
+ var CryptoWrapper = () => {
817
+ const { spreePayConfig, configIsLoading } = useSpreePayConfig();
818
+ const wagmiConfig = useMemo2(() => {
819
+ if (!spreePayConfig) return null;
820
+ return getCachedWagmiConfig(spreePayConfig.rainbowProjectId, spreePayConfig.rainbowAppName);
821
+ }, [spreePayConfig]);
822
+ if (configIsLoading || !wagmiConfig) return null;
823
+ return /* @__PURE__ */ jsx12(WagmiProvider, { config: wagmiConfig, children: /* @__PURE__ */ jsx12(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx12(RainbowKitProvider, { theme: lightTheme({ borderRadius: "large" }), children: /* @__PURE__ */ jsx12(NiceModal3.Provider, { children: /* @__PURE__ */ jsx12(Crypto, {}) }) }) }) });
824
+ };
825
+
826
+ // src/components/CryptoTab/CryptoTab.tsx
827
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
828
+ var CryptoTab = ({ isLoggedIn }) => {
829
+ const { spreePayConfig } = useSpreePayConfig();
830
+ return /* @__PURE__ */ jsxs8("div", { children: [
831
+ /* @__PURE__ */ jsx13("div", { className: "border-b border-(--border-component-specific-card) px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx13(CryptoWrapper, {}) }),
832
+ !spreePayConfig?.crypto.hidePoints && /* @__PURE__ */ jsx13("div", { className: "border-b border-(--border-component-specific-card) px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx13(PointsSwitch, { disabled: true, message: spreePayConfig?.crypto.pointsInfoMessage }) }),
833
+ /* @__PURE__ */ jsx13(CheckoutButton, { isLoggedIn })
834
+ ] });
835
+ };
836
+ export {
837
+ CryptoTab
838
+ };