forgelayer-react 1.0.0 → 1.1.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,478 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/index.js
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
+ ForgeLayerButton: () => ForgeLayerButton,
33
+ ForgeLayerModal: () => ForgeLayerModal,
34
+ useForgeLayerCheckout: () => useForgeLayerCheckout
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/ForgeLayerButton.jsx
39
+ var import_react3 = __toESM(require("react"));
40
+
41
+ // src/useForgeLayerCheckout.js
42
+ var import_react = require("react");
43
+ function useForgeLayerCheckout({
44
+ baseUrl = "/fl",
45
+ pollInterval = 15e3,
46
+ onSuccess,
47
+ onExpired,
48
+ onError,
49
+ onOpen,
50
+ onClose: onCloseProp
51
+ } = {}) {
52
+ const [modalState, setModalState] = (0, import_react.useState)("closed");
53
+ const [order, setOrder] = (0, import_react.useState)(null);
54
+ const [timeLeft, setTimeLeft] = (0, import_react.useState)(null);
55
+ const [error, setError] = (0, import_react.useState)(null);
56
+ const pollRef = (0, import_react.useRef)(null);
57
+ const cdRef = (0, import_react.useRef)(null);
58
+ const stopTimers = (0, import_react.useCallback)(() => {
59
+ if (pollRef.current) {
60
+ clearInterval(pollRef.current);
61
+ pollRef.current = null;
62
+ }
63
+ if (cdRef.current) {
64
+ clearInterval(cdRef.current);
65
+ cdRef.current = null;
66
+ }
67
+ }, []);
68
+ (0, import_react.useEffect)(() => stopTimers, [stopTimers]);
69
+ const close = (0, import_react.useCallback)(() => {
70
+ stopTimers();
71
+ setModalState("closed");
72
+ setOrder(null);
73
+ setTimeLeft(null);
74
+ setError(null);
75
+ onCloseProp?.();
76
+ }, [stopTimers, onCloseProp]);
77
+ const startCountdown = (0, import_react.useCallback)((expiresAt) => {
78
+ if (cdRef.current) clearInterval(cdRef.current);
79
+ const tick = () => {
80
+ const rem = expiresAt - Math.floor(Date.now() / 1e3);
81
+ setTimeLeft(rem <= 0 ? 0 : rem);
82
+ if (rem <= 0) clearInterval(cdRef.current);
83
+ };
84
+ tick();
85
+ cdRef.current = setInterval(tick, 1e3);
86
+ }, []);
87
+ const startPolling = (0, import_react.useCallback)((orderData) => {
88
+ if (pollRef.current) clearInterval(pollRef.current);
89
+ pollRef.current = setInterval(async () => {
90
+ try {
91
+ const res = await fetch(`${baseUrl}/status?session=${encodeURIComponent(orderData.sessionKey)}`);
92
+ const data = await res.json();
93
+ if (!data.ok) return;
94
+ if (data.status === "confirmed") {
95
+ stopTimers();
96
+ setModalState("success");
97
+ onSuccess?.(orderData);
98
+ } else if (data.status === "expired") {
99
+ stopTimers();
100
+ setModalState("expired");
101
+ onExpired?.();
102
+ }
103
+ } catch (_) {
104
+ }
105
+ }, pollInterval);
106
+ }, [baseUrl, pollInterval, stopTimers, onSuccess, onExpired]);
107
+ const open = (0, import_react.useCallback)(async (params) => {
108
+ stopTimers();
109
+ setModalState("loading");
110
+ setOrder(null);
111
+ setTimeLeft(null);
112
+ setError(null);
113
+ onOpen?.();
114
+ try {
115
+ const res = await fetch(`${baseUrl}/create`, {
116
+ method: "POST",
117
+ headers: { "Content-Type": "application/json" },
118
+ body: JSON.stringify(params)
119
+ });
120
+ const data = await res.json();
121
+ if (!data.ok) throw new Error(data.error || "Failed to generate payment address.");
122
+ setOrder(data);
123
+ setModalState("payment");
124
+ startCountdown(data.expiresAt);
125
+ startPolling(data);
126
+ } catch (e) {
127
+ setError(e.message);
128
+ setModalState("error");
129
+ onError?.(e);
130
+ }
131
+ }, [baseUrl, stopTimers, startCountdown, startPolling, onOpen, onError]);
132
+ return { modalState, order, timeLeft, error, open, close };
133
+ }
134
+
135
+ // src/ForgeLayerModal.jsx
136
+ var import_react2 = __toESM(require("react"));
137
+ var import_jsx_runtime = require("react/jsx-runtime");
138
+ var MODAL_CSS = `
139
+ @keyframes fl-r-fade{from{opacity:0}to{opacity:1}}
140
+ @keyframes fl-r-up{from{transform:translateY(16px);opacity:0}to{transform:translateY(0);opacity:1}}
141
+ @keyframes fl-r-spin{to{transform:rotate(360deg)}}
142
+ @keyframes fl-r-pulse{0%,100%{opacity:1}50%{opacity:.35}}
143
+ .fl-r-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:99999;
144
+ display:flex;align-items:center;justify-content:center;padding:16px;
145
+ animation:fl-r-fade .18s ease}
146
+ .fl-r-modal{background:#fff;border-radius:16px;width:100%;max-width:520px;
147
+ box-shadow:0 24px 64px rgba(0,0,0,.28);overflow:hidden;
148
+ animation:fl-r-up .22s ease;
149
+ font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
150
+ font-size:14px;color:#111}
151
+ .fl-r-spinner{width:38px;height:38px;border:3px solid #e5e7eb;
152
+ border-top-color:#f7931a;border-radius:50%;
153
+ animation:fl-r-spin .7s linear infinite;margin:0 auto 14px}
154
+ .fl-r-dot-pending{background:#f59e0b;animation:fl-r-pulse 1.6s ease-in-out infinite}
155
+ .fl-r-dot-confirmed{background:#10b981}
156
+ .fl-r-dot-expired{background:#ef4444}
157
+ .fl-r-xbtn:hover{background:#f3f4f6 !important;color:#111 !important}
158
+ .fl-r-cpbtn:hover{background:#f3f4f6 !important}
159
+ .fl-r-cpbtn-copied{border-color:#10b981 !important;color:#059669 !important}
160
+ @media(max-width:460px){.fl-r-grid{flex-direction:column !important;align-items:center !important}}
161
+ `;
162
+ var _cssInjected = false;
163
+ function ensureCSS() {
164
+ if (_cssInjected || typeof document === "undefined") return;
165
+ _cssInjected = true;
166
+ const el = document.createElement("style");
167
+ el.textContent = MODAL_CSS;
168
+ document.head.appendChild(el);
169
+ }
170
+ function fmtTime(secs) {
171
+ const m = Math.floor(secs / 60);
172
+ const s = secs % 60;
173
+ return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
174
+ }
175
+ function ForgeLayerModal({ modalState, order, timeLeft, error, onClose }) {
176
+ const [copied, setCopied] = (0, import_react2.useState)(false);
177
+ (0, import_react2.useEffect)(() => {
178
+ ensureCSS();
179
+ }, []);
180
+ (0, import_react2.useEffect)(() => {
181
+ const handler = (e) => {
182
+ if (e.key === "Escape") onClose();
183
+ };
184
+ document.addEventListener("keydown", handler);
185
+ return () => document.removeEventListener("keydown", handler);
186
+ }, [onClose]);
187
+ (0, import_react2.useEffect)(() => {
188
+ const prev = document.body.style.overflow;
189
+ document.body.style.overflow = "hidden";
190
+ return () => {
191
+ document.body.style.overflow = prev;
192
+ };
193
+ }, []);
194
+ const copyAddress = () => {
195
+ if (!order?.address) return;
196
+ navigator.clipboard?.writeText(order.address).catch(() => {
197
+ });
198
+ setCopied(true);
199
+ setTimeout(() => setCopied(false), 2e3);
200
+ };
201
+ const urgent = timeLeft !== null && timeLeft <= 120;
202
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
203
+ "div",
204
+ {
205
+ className: "fl-r-backdrop",
206
+ role: "dialog",
207
+ "aria-modal": "true",
208
+ "aria-label": "Crypto payment",
209
+ onClick: (e) => {
210
+ if (e.target === e.currentTarget) onClose();
211
+ },
212
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "fl-r-modal", children: [
213
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
214
+ display: "flex",
215
+ alignItems: "center",
216
+ justifyContent: "space-between",
217
+ padding: "16px 18px",
218
+ borderBottom: "1px solid #e5e7eb",
219
+ background: "#fafafa"
220
+ }, children: [
221
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 9, fontSize: 15, fontWeight: 700 }, children: [
222
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
223
+ width: 26,
224
+ height: 26,
225
+ background: "#f7931a",
226
+ borderRadius: 6,
227
+ display: "flex",
228
+ alignItems: "center",
229
+ justifyContent: "center",
230
+ color: "#fff",
231
+ fontSize: 10,
232
+ fontWeight: 800,
233
+ flexShrink: 0
234
+ }, children: "FL" }),
235
+ "Pay with Crypto"
236
+ ] }),
237
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
238
+ "button",
239
+ {
240
+ className: "fl-r-xbtn",
241
+ onClick: onClose,
242
+ "aria-label": "Close",
243
+ style: {
244
+ background: "none",
245
+ border: "none",
246
+ fontSize: 22,
247
+ lineHeight: 1,
248
+ cursor: "pointer",
249
+ color: "#6b7280",
250
+ padding: "4px 8px",
251
+ borderRadius: 5,
252
+ transition: "background .12s"
253
+ },
254
+ children: "\xD7"
255
+ }
256
+ )
257
+ ] }),
258
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: "20px 18px" }, children: [
259
+ modalState === "loading" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center", padding: "28px 0" }, children: [
260
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "fl-r-spinner" }),
261
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { color: "#6b7280", fontSize: 13, margin: 0 }, children: "Generating payment address\u2026" })
262
+ ] }),
263
+ modalState === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center", padding: "28px 0" }, children: [
264
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 48, marginBottom: 12 }, children: "\u26A0\uFE0F" }),
265
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 15, fontWeight: 700, marginBottom: 8 }, children: "Something went wrong" }),
266
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 13, color: "#6b7280" }, children: error })
267
+ ] }),
268
+ modalState === "payment" && order && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
270
+ display: "flex",
271
+ alignItems: "center",
272
+ gap: 9,
273
+ padding: "9px 13px",
274
+ borderRadius: 8,
275
+ background: "#f9fafb",
276
+ border: "1px solid #e5e7eb",
277
+ marginBottom: 14,
278
+ fontSize: 13
279
+ }, children: [
280
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
281
+ "span",
282
+ {
283
+ className: "fl-r-dot-pending",
284
+ style: { width: 8, height: 8, borderRadius: "50%", flexShrink: 0 }
285
+ }
286
+ ),
287
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Awaiting payment\u2026" }),
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
289
+ marginLeft: "auto",
290
+ fontWeight: 600,
291
+ fontSize: 13,
292
+ color: urgent ? "#ef4444" : "#374151",
293
+ fontVariantNumeric: "tabular-nums"
294
+ }, children: timeLeft !== null ? fmtTime(timeLeft) : "--:--" })
295
+ ] }),
296
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
297
+ background: "#fffbeb",
298
+ border: "1px solid #fde68a",
299
+ borderRadius: 8,
300
+ padding: "9px 13px",
301
+ fontSize: 12,
302
+ color: "#92400e",
303
+ marginBottom: 14,
304
+ lineHeight: 1.5
305
+ }, children: [
306
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u26A0 Important:" }),
307
+ " Send only ",
308
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: order.token }),
309
+ " on the",
310
+ " ",
311
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: order.chainName }),
312
+ " network only. Wrong network = permanent loss."
313
+ ] }),
314
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "fl-r-grid", style: { display: "flex", gap: 18, marginBottom: 14 }, children: [
315
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { flexShrink: 0, display: "flex", flexDirection: "column", alignItems: "center", gap: 6 }, children: [
316
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
317
+ "img",
318
+ {
319
+ src: order.qrUrl,
320
+ alt: `Send to ${order.address}`,
321
+ width: 148,
322
+ height: 148,
323
+ style: { border: "1px solid #e5e7eb", borderRadius: 10, display: "block", background: "#f9fafb" }
324
+ }
325
+ ),
326
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: 11, color: "#9ca3af", margin: 0 }, children: "Scan with wallet" })
327
+ ] }),
328
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: 13 }, children: [
329
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
330
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { style: { display: "block", fontSize: 10, fontWeight: 700, color: "#6b7280", textTransform: "uppercase", letterSpacing: ".06em", marginBottom: 4 }, children: "Amount to Send" }),
331
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 22, fontWeight: 700, lineHeight: 1.2 }, children: order.cryptoAmount ? `${parseFloat(order.cryptoAmount).toFixed(8).replace(/\.?0+$/, "")} ${order.token}` : `${order.currency} ${parseFloat(order.amount).toFixed(2)}` }),
332
+ order.cryptoAmount && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { fontSize: 12, color: "#6b7280", marginTop: 2 }, children: [
333
+ "\u2248 ",
334
+ order.currency,
335
+ " ",
336
+ parseFloat(order.amount).toFixed(2)
337
+ ] })
338
+ ] }),
339
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { style: { display: "block", fontSize: 10, fontWeight: 700, color: "#6b7280", textTransform: "uppercase", letterSpacing: ".06em", marginBottom: 4 }, children: "Deposit Address" }),
341
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "flex-start", gap: 7 }, children: [
342
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontFamily: "monospace", fontSize: 12, color: "#374151", wordBreak: "break-all", flex: 1, lineHeight: 1.5 }, children: order.address }),
343
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
344
+ "button",
345
+ {
346
+ className: `fl-r-cpbtn${copied ? " fl-r-cpbtn-copied" : ""}`,
347
+ onClick: copyAddress,
348
+ style: {
349
+ flexShrink: 0,
350
+ background: "#fff",
351
+ border: "1px solid #d1d5db",
352
+ borderRadius: 6,
353
+ padding: "5px 11px",
354
+ fontSize: 12,
355
+ cursor: "pointer",
356
+ color: "#374151",
357
+ transition: "background .12s",
358
+ whiteSpace: "nowrap"
359
+ },
360
+ children: copied ? "Copied!" : "Copy"
361
+ }
362
+ )
363
+ ] })
364
+ ] }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
366
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { style: { display: "block", fontSize: 10, fontWeight: 700, color: "#6b7280", textTransform: "uppercase", letterSpacing: ".06em", marginBottom: 4 }, children: "Network" }),
367
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { display: "inline-flex", alignItems: "center", gap: 5, padding: "3px 10px", background: "#f3f4f6", borderRadius: 100, fontSize: 12, fontWeight: 500, color: "#374151" }, children: [
368
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { width: 7, height: 7, borderRadius: "50%", background: "#10b981", flexShrink: 0 } }),
369
+ order.chainName,
370
+ " \xB7 ",
371
+ order.token
372
+ ] })
373
+ ] })
374
+ ] })
375
+ ] })
376
+ ] }),
377
+ modalState === "success" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center", padding: "30px 16px" }, children: [
378
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 52, marginBottom: 14 }, children: "\u2705" }),
379
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 19, fontWeight: 700, color: "#111", marginBottom: 7 }, children: "Payment Confirmed!" }),
380
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 13, color: "#6b7280" }, children: "Your payment has been received." })
381
+ ] }),
382
+ modalState === "expired" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center", padding: "30px 16px" }, children: [
383
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 52, marginBottom: 14 }, children: "\u23F3" }),
384
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 19, fontWeight: 700, color: "#111", marginBottom: 7 }, children: "Payment Expired" }),
385
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 13, color: "#6b7280" }, children: "The payment window has closed. Please start a new payment." })
386
+ ] })
387
+ ] }),
388
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: "10px 18px 14px", textAlign: "center", fontSize: 11, color: "#9ca3af", borderTop: "1px solid #f3f4f6" }, children: [
389
+ "Secured by",
390
+ " ",
391
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://forgelayer.io", target: "_blank", rel: "noopener noreferrer", style: { color: "#f7931a", textDecoration: "none" }, children: "ForgeLayer" })
392
+ ] })
393
+ ] })
394
+ }
395
+ );
396
+ }
397
+
398
+ // src/ForgeLayerButton.jsx
399
+ var import_jsx_runtime2 = require("react/jsx-runtime");
400
+ function ForgeLayerButton({
401
+ // Payment params
402
+ amount,
403
+ currency = "USD",
404
+ chain = "ethereum",
405
+ token = "USDT",
406
+ orderId,
407
+ paymentWindow,
408
+ reuseAddress,
409
+ // Backend base path (proxied or absolute)
410
+ baseUrl = "/fl",
411
+ pollInterval,
412
+ // Button UI
413
+ label,
414
+ children,
415
+ className,
416
+ style,
417
+ disabled,
418
+ // Callbacks
419
+ onSuccess,
420
+ onExpired,
421
+ onError,
422
+ onOpen,
423
+ onClose
424
+ }) {
425
+ const { modalState, order, timeLeft, error, open, close } = useForgeLayerCheckout({
426
+ baseUrl,
427
+ pollInterval,
428
+ onSuccess,
429
+ onExpired,
430
+ onError,
431
+ onOpen,
432
+ onClose
433
+ });
434
+ const isOpen = modalState !== "closed";
435
+ const handleClick = () => {
436
+ open({ amount, currency, chain, token, orderId, paymentWindow, reuseAddress });
437
+ };
438
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
439
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
440
+ "button",
441
+ {
442
+ onClick: handleClick,
443
+ disabled: disabled || isOpen,
444
+ className,
445
+ style: {
446
+ display: "inline-flex",
447
+ alignItems: "center",
448
+ gap: 8,
449
+ padding: "12px 24px",
450
+ background: "#f7931a",
451
+ color: "#fff",
452
+ border: "none",
453
+ borderRadius: 8,
454
+ fontSize: 15,
455
+ fontWeight: 600,
456
+ cursor: disabled || isOpen ? "not-allowed" : "pointer",
457
+ opacity: disabled || isOpen ? 0.65 : 1,
458
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
459
+ lineHeight: 1.2,
460
+ transition: "opacity .15s",
461
+ ...style
462
+ },
463
+ children: label ?? children ?? "Pay with Crypto"
464
+ }
465
+ ),
466
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
467
+ ForgeLayerModal,
468
+ {
469
+ modalState,
470
+ order,
471
+ timeLeft,
472
+ error,
473
+ onClose: close
474
+ }
475
+ )
476
+ ] });
477
+ }
478
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.js", "../src/ForgeLayerButton.jsx", "../src/useForgeLayerCheckout.js", "../src/ForgeLayerModal.jsx"],
4
+ "sourcesContent": ["export { ForgeLayerButton } from './ForgeLayerButton.jsx';\nexport { ForgeLayerModal } from './ForgeLayerModal.jsx';\nexport { useForgeLayerCheckout } from './useForgeLayerCheckout.js';\n", "import React from 'react';\nimport { useForgeLayerCheckout } from './useForgeLayerCheckout.js';\nimport { ForgeLayerModal } from './ForgeLayerModal.jsx';\n\n/**\n * Drop-in React checkout button.\n *\n * Usage:\n * <ForgeLayerButton\n * amount={49.99}\n * currency=\"USD\"\n * chain=\"ethereum\"\n * token=\"USDT\"\n * orderId=\"ORDER-123\"\n * onSuccess={(order) => router.push('/thank-you')}\n * >\n * Pay $49.99\n * </ForgeLayerButton>\n */\nexport function ForgeLayerButton({\n // Payment params\n amount,\n currency = 'USD',\n chain = 'ethereum',\n token = 'USDT',\n orderId,\n paymentWindow,\n reuseAddress,\n // Backend base path (proxied or absolute)\n baseUrl = '/fl',\n pollInterval,\n // Button UI\n label,\n children,\n className,\n style,\n disabled,\n // Callbacks\n onSuccess,\n onExpired,\n onError,\n onOpen,\n onClose,\n}) {\n const { modalState, order, timeLeft, error, open, close } = useForgeLayerCheckout({\n baseUrl,\n pollInterval,\n onSuccess,\n onExpired,\n onError,\n onOpen,\n onClose,\n });\n\n const isOpen = modalState !== 'closed';\n\n const handleClick = () => {\n open({ amount, currency, chain, token, orderId, paymentWindow, reuseAddress });\n };\n\n return (\n <>\n <button\n onClick={handleClick}\n disabled={disabled || isOpen}\n className={className}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n padding: '12px 24px',\n background: '#f7931a',\n color: '#fff',\n border: 'none',\n borderRadius: 8,\n fontSize: 15,\n fontWeight: 600,\n cursor: (disabled || isOpen) ? 'not-allowed' : 'pointer',\n opacity: (disabled || isOpen) ? 0.65 : 1,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n lineHeight: 1.2,\n transition: 'opacity .15s',\n ...style,\n }}\n >\n {label ?? children ?? 'Pay with Crypto'}\n </button>\n\n {isOpen && (\n <ForgeLayerModal\n modalState={modalState}\n order={order}\n timeLeft={timeLeft}\n error={error}\n onClose={close}\n />\n )}\n </>\n );\n}\n", "'use strict';\nimport { useState, useRef, useCallback, useEffect } from 'react';\n\n/**\n * Core hook \u2014 handles all state and API calls for the checkout flow.\n *\n * modalState values:\n * 'closed' | 'loading' | 'payment' | 'success' | 'expired' | 'error'\n */\nexport function useForgeLayerCheckout({\n baseUrl = '/fl',\n pollInterval = 15_000,\n onSuccess,\n onExpired,\n onError,\n onOpen,\n onClose: onCloseProp,\n} = {}) {\n const [modalState, setModalState] = useState('closed');\n const [order, setOrder] = useState(null);\n const [timeLeft, setTimeLeft] = useState(null);\n const [error, setError] = useState(null);\n\n const pollRef = useRef(null);\n const cdRef = useRef(null);\n\n const stopTimers = useCallback(() => {\n if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; }\n if (cdRef.current) { clearInterval(cdRef.current); cdRef.current = null; }\n }, []);\n\n // Cleanup on unmount\n useEffect(() => stopTimers, [stopTimers]);\n\n const close = useCallback(() => {\n stopTimers();\n setModalState('closed');\n setOrder(null);\n setTimeLeft(null);\n setError(null);\n onCloseProp?.();\n }, [stopTimers, onCloseProp]);\n\n const startCountdown = useCallback((expiresAt) => {\n if (cdRef.current) clearInterval(cdRef.current);\n const tick = () => {\n const rem = expiresAt - Math.floor(Date.now() / 1000);\n setTimeLeft(rem <= 0 ? 0 : rem);\n if (rem <= 0) clearInterval(cdRef.current);\n };\n tick();\n cdRef.current = setInterval(tick, 1000);\n }, []);\n\n const startPolling = useCallback((orderData) => {\n if (pollRef.current) clearInterval(pollRef.current);\n pollRef.current = setInterval(async () => {\n try {\n const res = await fetch(`${baseUrl}/status?session=${encodeURIComponent(orderData.sessionKey)}`);\n const data = await res.json();\n if (!data.ok) return;\n if (data.status === 'confirmed') {\n stopTimers();\n setModalState('success');\n onSuccess?.(orderData);\n } else if (data.status === 'expired') {\n stopTimers();\n setModalState('expired');\n onExpired?.();\n }\n } catch (_) {}\n }, pollInterval);\n }, [baseUrl, pollInterval, stopTimers, onSuccess, onExpired]);\n\n const open = useCallback(async (params) => {\n stopTimers();\n setModalState('loading');\n setOrder(null);\n setTimeLeft(null);\n setError(null);\n onOpen?.();\n\n try {\n const res = await fetch(`${baseUrl}/create`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(params),\n });\n const data = await res.json();\n if (!data.ok) throw new Error(data.error || 'Failed to generate payment address.');\n setOrder(data);\n setModalState('payment');\n startCountdown(data.expiresAt);\n startPolling(data);\n } catch (e) {\n setError(e.message);\n setModalState('error');\n onError?.(e);\n }\n }, [baseUrl, stopTimers, startCountdown, startPolling, onOpen, onError]);\n\n return { modalState, order, timeLeft, error, open, close };\n}\n", "import React, { useEffect, useState } from 'react';\n\n// Injected once \u2014 handles animations, hover, and pseudo-elements\n// that can't be done with inline styles.\nconst MODAL_CSS = `\n@keyframes fl-r-fade{from{opacity:0}to{opacity:1}}\n@keyframes fl-r-up{from{transform:translateY(16px);opacity:0}to{transform:translateY(0);opacity:1}}\n@keyframes fl-r-spin{to{transform:rotate(360deg)}}\n@keyframes fl-r-pulse{0%,100%{opacity:1}50%{opacity:.35}}\n.fl-r-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:99999;\n display:flex;align-items:center;justify-content:center;padding:16px;\n animation:fl-r-fade .18s ease}\n.fl-r-modal{background:#fff;border-radius:16px;width:100%;max-width:520px;\n box-shadow:0 24px 64px rgba(0,0,0,.28);overflow:hidden;\n animation:fl-r-up .22s ease;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\n font-size:14px;color:#111}\n.fl-r-spinner{width:38px;height:38px;border:3px solid #e5e7eb;\n border-top-color:#f7931a;border-radius:50%;\n animation:fl-r-spin .7s linear infinite;margin:0 auto 14px}\n.fl-r-dot-pending{background:#f59e0b;animation:fl-r-pulse 1.6s ease-in-out infinite}\n.fl-r-dot-confirmed{background:#10b981}\n.fl-r-dot-expired{background:#ef4444}\n.fl-r-xbtn:hover{background:#f3f4f6 !important;color:#111 !important}\n.fl-r-cpbtn:hover{background:#f3f4f6 !important}\n.fl-r-cpbtn-copied{border-color:#10b981 !important;color:#059669 !important}\n@media(max-width:460px){.fl-r-grid{flex-direction:column !important;align-items:center !important}}\n`;\n\nlet _cssInjected = false;\nfunction ensureCSS() {\n if (_cssInjected || typeof document === 'undefined') return;\n _cssInjected = true;\n const el = document.createElement('style');\n el.textContent = MODAL_CSS;\n document.head.appendChild(el);\n}\n\nfunction fmtTime(secs) {\n const m = Math.floor(secs / 60);\n const s = secs % 60;\n return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;\n}\n\nexport function ForgeLayerModal({ modalState, order, timeLeft, error, onClose }) {\n const [copied, setCopied] = useState(false);\n\n useEffect(() => { ensureCSS(); }, []);\n\n // Escape key\n useEffect(() => {\n const handler = (e) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [onClose]);\n\n // Lock body scroll\n useEffect(() => {\n const prev = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => { document.body.style.overflow = prev; };\n }, []);\n\n const copyAddress = () => {\n if (!order?.address) return;\n navigator.clipboard?.writeText(order.address).catch(() => {});\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const urgent = timeLeft !== null && timeLeft <= 120;\n\n return (\n <div\n className=\"fl-r-backdrop\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Crypto payment\"\n onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}\n >\n <div className=\"fl-r-modal\">\n\n {/* \u2500\u2500 Header \u2500\u2500 */}\n <div style={{\n display: 'flex', alignItems: 'center', justifyContent: 'space-between',\n padding: '16px 18px', borderBottom: '1px solid #e5e7eb', background: '#fafafa',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 9, fontSize: 15, fontWeight: 700 }}>\n <div style={{\n width: 26, height: 26, background: '#f7931a', borderRadius: 6,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n color: '#fff', fontSize: 10, fontWeight: 800, flexShrink: 0,\n }}>FL</div>\n Pay with Crypto\n </div>\n <button\n className=\"fl-r-xbtn\"\n onClick={onClose}\n aria-label=\"Close\"\n style={{\n background: 'none', border: 'none', fontSize: 22, lineHeight: 1,\n cursor: 'pointer', color: '#6b7280', padding: '4px 8px',\n borderRadius: 5, transition: 'background .12s',\n }}\n >\u00D7</button>\n </div>\n\n {/* \u2500\u2500 Body \u2500\u2500 */}\n <div style={{ padding: '20px 18px' }}>\n\n {/* Loading */}\n {modalState === 'loading' && (\n <div style={{ textAlign: 'center', padding: '28px 0' }}>\n <div className=\"fl-r-spinner\" />\n <p style={{ color: '#6b7280', fontSize: 13, margin: 0 }}>\n Generating payment address\u2026\n </p>\n </div>\n )}\n\n {/* Error */}\n {modalState === 'error' && (\n <div style={{ textAlign: 'center', padding: '28px 0' }}>\n <div style={{ fontSize: 48, marginBottom: 12 }}>\u26A0\uFE0F</div>\n <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 8 }}>Something went wrong</div>\n <div style={{ fontSize: 13, color: '#6b7280' }}>{error}</div>\n </div>\n )}\n\n {/* Payment */}\n {modalState === 'payment' && order && (\n <>\n {/* Status bar */}\n <div style={{\n display: 'flex', alignItems: 'center', gap: 9,\n padding: '9px 13px', borderRadius: 8,\n background: '#f9fafb', border: '1px solid #e5e7eb',\n marginBottom: 14, fontSize: 13,\n }}>\n <span\n className=\"fl-r-dot-pending\"\n style={{ width: 8, height: 8, borderRadius: '50%', flexShrink: 0 }}\n />\n <span>Awaiting payment\u2026</span>\n <span style={{\n marginLeft: 'auto', fontWeight: 600, fontSize: 13,\n color: urgent ? '#ef4444' : '#374151',\n fontVariantNumeric: 'tabular-nums',\n }}>\n {timeLeft !== null ? fmtTime(timeLeft) : '--:--'}\n </span>\n </div>\n\n {/* Network warning */}\n <div style={{\n background: '#fffbeb', border: '1px solid #fde68a', borderRadius: 8,\n padding: '9px 13px', fontSize: 12, color: '#92400e',\n marginBottom: 14, lineHeight: 1.5,\n }}>\n <strong>\u26A0 Important:</strong> Send only <strong>{order.token}</strong> on the{' '}\n <strong>{order.chainName}</strong> network only. Wrong network = permanent loss.\n </div>\n\n {/* QR + info grid */}\n <div className=\"fl-r-grid\" style={{ display: 'flex', gap: 18, marginBottom: 14 }}>\n {/* QR side */}\n <div style={{ flexShrink: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>\n <img\n src={order.qrUrl}\n alt={`Send to ${order.address}`}\n width={148}\n height={148}\n style={{ border: '1px solid #e5e7eb', borderRadius: 10, display: 'block', background: '#f9fafb' }}\n />\n <p style={{ fontSize: 11, color: '#9ca3af', margin: 0 }}>Scan with wallet</p>\n </div>\n\n {/* Info side */}\n <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 13 }}>\n {/* Amount */}\n <div>\n <label style={{ display: 'block', fontSize: 10, fontWeight: 700, color: '#6b7280', textTransform: 'uppercase', letterSpacing: '.06em', marginBottom: 4 }}>\n Amount to Send\n </label>\n <div style={{ fontSize: 22, fontWeight: 700, lineHeight: 1.2 }}>\n {order.cryptoAmount\n ? `${parseFloat(order.cryptoAmount).toFixed(8).replace(/\\.?0+$/, '')} ${order.token}`\n : `${order.currency} ${parseFloat(order.amount).toFixed(2)}`}\n </div>\n {order.cryptoAmount && (\n <div style={{ fontSize: 12, color: '#6b7280', marginTop: 2 }}>\n \u2248 {order.currency} {parseFloat(order.amount).toFixed(2)}\n </div>\n )}\n </div>\n\n {/* Address */}\n <div>\n <label style={{ display: 'block', fontSize: 10, fontWeight: 700, color: '#6b7280', textTransform: 'uppercase', letterSpacing: '.06em', marginBottom: 4 }}>\n Deposit Address\n </label>\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 7 }}>\n <span style={{ fontFamily: 'monospace', fontSize: 12, color: '#374151', wordBreak: 'break-all', flex: 1, lineHeight: 1.5 }}>\n {order.address}\n </span>\n <button\n className={`fl-r-cpbtn${copied ? ' fl-r-cpbtn-copied' : ''}`}\n onClick={copyAddress}\n style={{\n flexShrink: 0, background: '#fff', border: '1px solid #d1d5db',\n borderRadius: 6, padding: '5px 11px', fontSize: 12,\n cursor: 'pointer', color: '#374151',\n transition: 'background .12s', whiteSpace: 'nowrap',\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n </div>\n </div>\n\n {/* Network badge */}\n <div>\n <label style={{ display: 'block', fontSize: 10, fontWeight: 700, color: '#6b7280', textTransform: 'uppercase', letterSpacing: '.06em', marginBottom: 4 }}>\n Network\n </label>\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '3px 10px', background: '#f3f4f6', borderRadius: 100, fontSize: 12, fontWeight: 500, color: '#374151' }}>\n <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#10b981', flexShrink: 0 }} />\n {order.chainName} \u00B7 {order.token}\n </span>\n </div>\n </div>\n </div>\n </>\n )}\n\n {/* Success */}\n {modalState === 'success' && (\n <div style={{ textAlign: 'center', padding: '30px 16px' }}>\n <div style={{ fontSize: 52, marginBottom: 14 }}>\u2705</div>\n <div style={{ fontSize: 19, fontWeight: 700, color: '#111', marginBottom: 7 }}>Payment Confirmed!</div>\n <div style={{ fontSize: 13, color: '#6b7280' }}>Your payment has been received.</div>\n </div>\n )}\n\n {/* Expired */}\n {modalState === 'expired' && (\n <div style={{ textAlign: 'center', padding: '30px 16px' }}>\n <div style={{ fontSize: 52, marginBottom: 14 }}>\u23F3</div>\n <div style={{ fontSize: 19, fontWeight: 700, color: '#111', marginBottom: 7 }}>Payment Expired</div>\n <div style={{ fontSize: 13, color: '#6b7280' }}>\n The payment window has closed. Please start a new payment.\n </div>\n </div>\n )}\n </div>\n\n {/* \u2500\u2500 Footer \u2500\u2500 */}\n <div style={{ padding: '10px 18px 14px', textAlign: 'center', fontSize: 11, color: '#9ca3af', borderTop: '1px solid #f3f4f6' }}>\n Secured by{' '}\n <a href=\"https://forgelayer.io\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: '#f7931a', textDecoration: 'none' }}>\n ForgeLayer\n </a>\n </div>\n </div>\n </div>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_react", "import_react", "import_jsx_runtime"]
7
+ }