@openreceive/react 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +15 -1
- package/dist/index.js +532 -364
- package/dist/styles.css +1 -1
- package/package.json +4 -3
- package/skills/debug-openreceive-payment/SKILL.md +88 -0
- package/skills/integrate-openreceive/SKILL.md +116 -0
- package/skills/integrate-openreceive/references/node.md +480 -0
- package/skills/integrate-openreceive/references/rails.md +568 -0
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
// src/checkout.ts
|
|
2
2
|
import {
|
|
3
|
+
checkoutLabels as checkoutLabels6,
|
|
3
4
|
createLightningInvoiceDecodeUrl as createLightningInvoiceDecodeUrl2,
|
|
4
5
|
enterCheckoutResumePath,
|
|
5
6
|
mergeAttemptIntoCheckout,
|
|
6
7
|
mergeAttemptIntoSnapshot,
|
|
7
8
|
OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES as OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3,
|
|
8
9
|
OPENRECEIVE_DEFAULT_PREFIX,
|
|
9
|
-
checkoutLabels as checkoutLabels6,
|
|
10
10
|
orClasses as orClasses7,
|
|
11
11
|
prepareCheckout,
|
|
12
12
|
requestCheckout,
|
|
13
|
+
resumeSwapAttempt,
|
|
13
14
|
validateCheckoutProps
|
|
14
15
|
} from "@openreceive/browser/headless";
|
|
15
16
|
import * as React10 from "react";
|
|
@@ -429,106 +430,17 @@ function SatsDetail(props) {
|
|
|
429
430
|
);
|
|
430
431
|
}
|
|
431
432
|
|
|
432
|
-
// src/transaction-details.ts
|
|
433
|
-
import {
|
|
434
|
-
checkoutLabels as checkoutLabels2,
|
|
435
|
-
orClasses as orClasses2,
|
|
436
|
-
resolveTransactionDetailRows
|
|
437
|
-
} from "@openreceive/browser/headless";
|
|
438
|
-
import * as React4 from "react";
|
|
439
|
-
function TransactionDetails(props) {
|
|
440
|
-
const rows = resolveTransactionDetailRows(props.state);
|
|
441
|
-
if (rows.length === 0) return null;
|
|
442
|
-
return React4.createElement(
|
|
443
|
-
"details",
|
|
444
|
-
{
|
|
445
|
-
className: joinClassNames(orClasses2.transactionDetails, props.className),
|
|
446
|
-
open: props.open === true ? true : void 0
|
|
447
|
-
},
|
|
448
|
-
React4.createElement(
|
|
449
|
-
"summary",
|
|
450
|
-
{ className: orClasses2.transactionDetailsTitle },
|
|
451
|
-
checkoutLabels2.transactionDetails
|
|
452
|
-
),
|
|
453
|
-
React4.createElement(
|
|
454
|
-
"div",
|
|
455
|
-
{ className: orClasses2.transactionDetailsContent },
|
|
456
|
-
React4.createElement(
|
|
457
|
-
"dl",
|
|
458
|
-
{ className: orClasses2.swapDetails },
|
|
459
|
-
rows.flatMap(
|
|
460
|
-
(row) => renderTransactionDetailRow(row, {
|
|
461
|
-
clipboard: props.clipboard,
|
|
462
|
-
onError: props.onError
|
|
463
|
-
})
|
|
464
|
-
)
|
|
465
|
-
)
|
|
466
|
-
)
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
function renderTransactionDetailRow(row, options) {
|
|
470
|
-
const copyValue = row.copyValue ?? row.value;
|
|
471
|
-
return [
|
|
472
|
-
React4.createElement(
|
|
473
|
-
"dt",
|
|
474
|
-
{ key: `${row.label}-label`, className: orClasses2.swapDetailsDt },
|
|
475
|
-
row.label
|
|
476
|
-
),
|
|
477
|
-
React4.createElement(
|
|
478
|
-
"dd",
|
|
479
|
-
{ key: `${row.label}-value`, className: orClasses2.swapDetailsDd },
|
|
480
|
-
React4.createElement("code", { className: orClasses2.swapDetailsCode }, row.value),
|
|
481
|
-
React4.createElement(
|
|
482
|
-
"div",
|
|
483
|
-
{ className: orClasses2.swapDetailsActions },
|
|
484
|
-
React4.createElement(TransactionDetailCopyButton, {
|
|
485
|
-
value: copyValue,
|
|
486
|
-
clipboard: options.clipboard,
|
|
487
|
-
onError: options.onError
|
|
488
|
-
}),
|
|
489
|
-
row.href === void 0 ? null : React4.createElement(
|
|
490
|
-
"a",
|
|
491
|
-
{
|
|
492
|
-
className: orClasses2.swapDetailsLink,
|
|
493
|
-
href: row.href,
|
|
494
|
-
rel: "noreferrer",
|
|
495
|
-
target: "_blank"
|
|
496
|
-
},
|
|
497
|
-
row.hrefLabel ?? checkoutLabels2.viewOnExplorer
|
|
498
|
-
)
|
|
499
|
-
)
|
|
500
|
-
)
|
|
501
|
-
];
|
|
502
|
-
}
|
|
503
|
-
function TransactionDetailCopyButton(props) {
|
|
504
|
-
const [copied, setCopied] = useTransientValue(false);
|
|
505
|
-
const label = copied ? checkoutLabels2.copied : "Copy";
|
|
506
|
-
return React4.createElement(
|
|
507
|
-
"button",
|
|
508
|
-
{
|
|
509
|
-
className: orClasses2.detailCopy,
|
|
510
|
-
type: "button",
|
|
511
|
-
"aria-label": label,
|
|
512
|
-
title: label,
|
|
513
|
-
onClick: () => {
|
|
514
|
-
void copyText(props.value, props.clipboard).then(() => setCopied(true)).catch((error) => props.onError?.(error));
|
|
515
|
-
}
|
|
516
|
-
},
|
|
517
|
-
React4.createElement(ClipboardIcon)
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
433
|
// src/theme.ts
|
|
522
|
-
import * as
|
|
434
|
+
import * as React4 from "react";
|
|
523
435
|
import {
|
|
524
436
|
OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES as OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES2,
|
|
525
437
|
OPENRECEIVE_THEME_STORAGE_KEY,
|
|
526
438
|
createThemeModel,
|
|
527
|
-
orClasses as
|
|
439
|
+
orClasses as orClasses2,
|
|
528
440
|
readThemePreference,
|
|
529
441
|
writeThemePreference
|
|
530
442
|
} from "@openreceive/browser/headless";
|
|
531
|
-
var ThemeContext =
|
|
443
|
+
var ThemeContext = React4.createContext(null);
|
|
532
444
|
var storedThemeListeners = /* @__PURE__ */ new Set();
|
|
533
445
|
var lastSetTheme = /* @__PURE__ */ new Map();
|
|
534
446
|
function notifyStoredThemeChange() {
|
|
@@ -557,9 +469,10 @@ function useLocalTheme(options = {}) {
|
|
|
557
469
|
const storageKey = options.storageKey ?? OPENRECEIVE_THEME_STORAGE_KEY;
|
|
558
470
|
const storage = options.storage;
|
|
559
471
|
const defaultTheme = options.defaultTheme;
|
|
560
|
-
const
|
|
472
|
+
const lockedTheme = options.theme;
|
|
473
|
+
const theme = React4.useSyncExternalStore(
|
|
561
474
|
subscribeStoredTheme,
|
|
562
|
-
|
|
475
|
+
React4.useCallback(
|
|
563
476
|
() => readThemePreference({
|
|
564
477
|
storage,
|
|
565
478
|
storageKey,
|
|
@@ -567,7 +480,7 @@ function useLocalTheme(options = {}) {
|
|
|
567
480
|
}),
|
|
568
481
|
[storage, storageKey, defaultTheme]
|
|
569
482
|
),
|
|
570
|
-
|
|
483
|
+
React4.useCallback(
|
|
571
484
|
() => (
|
|
572
485
|
// A host-supplied storage is readable on the server (that is how SSR theming is
|
|
573
486
|
// wired); the implicit browser localStorage is not, so fall back to the default.
|
|
@@ -576,14 +489,15 @@ function useLocalTheme(options = {}) {
|
|
|
576
489
|
[storage, storageKey, defaultTheme]
|
|
577
490
|
)
|
|
578
491
|
);
|
|
579
|
-
const systemDark =
|
|
492
|
+
const systemDark = React4.useSyncExternalStore(
|
|
580
493
|
subscribeSystemDark,
|
|
581
494
|
getSystemDark,
|
|
582
495
|
getServerSystemDark
|
|
583
496
|
);
|
|
584
|
-
const themeModel = createThemeModel(theme, { systemDark });
|
|
585
|
-
const setTheme =
|
|
497
|
+
const themeModel = createThemeModel(lockedTheme ?? theme, { systemDark });
|
|
498
|
+
const setTheme = React4.useCallback(
|
|
586
499
|
(nextTheme) => {
|
|
500
|
+
if (lockedTheme !== void 0) return;
|
|
587
501
|
lastSetTheme.set(storageKey, nextTheme);
|
|
588
502
|
writeThemePreference(nextTheme, {
|
|
589
503
|
storage,
|
|
@@ -591,13 +505,13 @@ function useLocalTheme(options = {}) {
|
|
|
591
505
|
});
|
|
592
506
|
notifyStoredThemeChange();
|
|
593
507
|
},
|
|
594
|
-
[storage, storageKey]
|
|
508
|
+
[storage, storageKey, lockedTheme]
|
|
595
509
|
);
|
|
596
|
-
const toggleTheme =
|
|
510
|
+
const toggleTheme = React4.useCallback(() => {
|
|
597
511
|
setTheme(themeModel.nextTheme);
|
|
598
512
|
}, [setTheme, themeModel.nextTheme]);
|
|
599
513
|
return {
|
|
600
|
-
theme,
|
|
514
|
+
theme: lockedTheme ?? theme,
|
|
601
515
|
resolvedTheme: themeModel.resolvedTheme,
|
|
602
516
|
model: themeModel,
|
|
603
517
|
nextTheme: themeModel.nextTheme,
|
|
@@ -610,10 +524,10 @@ function useLocalTheme(options = {}) {
|
|
|
610
524
|
};
|
|
611
525
|
}
|
|
612
526
|
function useTheme(options = {}) {
|
|
613
|
-
const scoped =
|
|
527
|
+
const scoped = React4.useContext(ThemeContext);
|
|
614
528
|
const local = useLocalTheme(options);
|
|
615
529
|
const storageKey = options.storageKey ?? OPENRECEIVE_THEME_STORAGE_KEY;
|
|
616
|
-
if (scoped !== null && options.storage === void 0 && (options.storageKey === void 0 || options.storageKey === storageKey) && options.defaultTheme === void 0) {
|
|
530
|
+
if (scoped !== null && options.theme === void 0 && options.storage === void 0 && (options.storageKey === void 0 || options.storageKey === storageKey) && options.defaultTheme === void 0) {
|
|
617
531
|
return { ...scoped, fromScope: true };
|
|
618
532
|
}
|
|
619
533
|
return local;
|
|
@@ -637,7 +551,7 @@ function ThemeToggle(props) {
|
|
|
637
551
|
const componentProps = {
|
|
638
552
|
...buttonProps,
|
|
639
553
|
"aria-label": themeModel.toggleLabel,
|
|
640
|
-
className: joinClassNames(
|
|
554
|
+
className: joinClassNames(orClasses2.themeToggle, buttonProps.className),
|
|
641
555
|
title: themeModel.toggleLabel,
|
|
642
556
|
type,
|
|
643
557
|
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES2.themeToggle]: "",
|
|
@@ -648,7 +562,7 @@ function ThemeToggle(props) {
|
|
|
648
562
|
if (onThemeChange === void 0) fallback.setTheme(themeModel.nextTheme);
|
|
649
563
|
}
|
|
650
564
|
};
|
|
651
|
-
return
|
|
565
|
+
return React4.createElement(ButtonComponent, componentProps, children ?? themeModel.toggleLabel);
|
|
652
566
|
}
|
|
653
567
|
function ThemeScope(props) {
|
|
654
568
|
const {
|
|
@@ -656,6 +570,7 @@ function ThemeScope(props) {
|
|
|
656
570
|
defaultTheme,
|
|
657
571
|
storageKey,
|
|
658
572
|
storage,
|
|
573
|
+
theme: lockedTheme,
|
|
659
574
|
themeToggle = false,
|
|
660
575
|
topbarClassName,
|
|
661
576
|
themeToggleClassName,
|
|
@@ -666,25 +581,27 @@ function ThemeScope(props) {
|
|
|
666
581
|
const theme = useLocalTheme({
|
|
667
582
|
defaultTheme,
|
|
668
583
|
storageKey,
|
|
669
|
-
storage
|
|
584
|
+
storage,
|
|
585
|
+
theme: lockedTheme
|
|
670
586
|
});
|
|
671
587
|
const scopedChildren = typeof children === "function" ? children(theme) : children;
|
|
672
|
-
|
|
588
|
+
const showsToggle = themeToggle && lockedTheme === void 0;
|
|
589
|
+
return React4.createElement(
|
|
673
590
|
ThemeContext.Provider,
|
|
674
591
|
{ value: theme },
|
|
675
592
|
// Variadic children, not an array: an array child needs a key on every entry.
|
|
676
|
-
|
|
593
|
+
React4.createElement(
|
|
677
594
|
Element,
|
|
678
595
|
{
|
|
679
596
|
...elementProps,
|
|
680
597
|
...theme.attributes
|
|
681
598
|
},
|
|
682
|
-
|
|
599
|
+
showsToggle ? React4.createElement(
|
|
683
600
|
"div",
|
|
684
601
|
{
|
|
685
602
|
className: topbarClassName
|
|
686
603
|
},
|
|
687
|
-
|
|
604
|
+
React4.createElement(ThemeToggle, {
|
|
688
605
|
className: themeToggleClassName,
|
|
689
606
|
theme: theme.theme,
|
|
690
607
|
resolvedTheme: theme.resolvedTheme,
|
|
@@ -697,6 +614,95 @@ function ThemeScope(props) {
|
|
|
697
614
|
);
|
|
698
615
|
}
|
|
699
616
|
|
|
617
|
+
// src/transaction-details.ts
|
|
618
|
+
import {
|
|
619
|
+
checkoutLabels as checkoutLabels2,
|
|
620
|
+
orClasses as orClasses3,
|
|
621
|
+
resolveTransactionDetailRows
|
|
622
|
+
} from "@openreceive/browser/headless";
|
|
623
|
+
import * as React5 from "react";
|
|
624
|
+
function TransactionDetails(props) {
|
|
625
|
+
const rows = resolveTransactionDetailRows(props.state);
|
|
626
|
+
if (rows.length === 0) return null;
|
|
627
|
+
return React5.createElement(
|
|
628
|
+
"details",
|
|
629
|
+
{
|
|
630
|
+
className: joinClassNames(orClasses3.transactionDetails, props.className),
|
|
631
|
+
open: props.open === true ? true : void 0
|
|
632
|
+
},
|
|
633
|
+
React5.createElement(
|
|
634
|
+
"summary",
|
|
635
|
+
{ className: orClasses3.transactionDetailsTitle },
|
|
636
|
+
checkoutLabels2.transactionDetails
|
|
637
|
+
),
|
|
638
|
+
React5.createElement(
|
|
639
|
+
"div",
|
|
640
|
+
{ className: orClasses3.transactionDetailsContent },
|
|
641
|
+
React5.createElement(
|
|
642
|
+
"dl",
|
|
643
|
+
{ className: orClasses3.swapDetails },
|
|
644
|
+
rows.flatMap(
|
|
645
|
+
(row) => renderTransactionDetailRow(row, {
|
|
646
|
+
clipboard: props.clipboard,
|
|
647
|
+
onError: props.onError
|
|
648
|
+
})
|
|
649
|
+
)
|
|
650
|
+
)
|
|
651
|
+
)
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
function renderTransactionDetailRow(row, options) {
|
|
655
|
+
const copyValue = row.copyValue ?? row.value;
|
|
656
|
+
return [
|
|
657
|
+
React5.createElement(
|
|
658
|
+
"dt",
|
|
659
|
+
{ key: `${row.label}-label`, className: orClasses3.swapDetailsDt },
|
|
660
|
+
row.label
|
|
661
|
+
),
|
|
662
|
+
React5.createElement(
|
|
663
|
+
"dd",
|
|
664
|
+
{ key: `${row.label}-value`, className: orClasses3.swapDetailsDd },
|
|
665
|
+
React5.createElement("code", { className: orClasses3.swapDetailsCode }, row.value),
|
|
666
|
+
React5.createElement(
|
|
667
|
+
"div",
|
|
668
|
+
{ className: orClasses3.swapDetailsActions },
|
|
669
|
+
React5.createElement(TransactionDetailCopyButton, {
|
|
670
|
+
value: copyValue,
|
|
671
|
+
clipboard: options.clipboard,
|
|
672
|
+
onError: options.onError
|
|
673
|
+
}),
|
|
674
|
+
row.href === void 0 ? null : React5.createElement(
|
|
675
|
+
"a",
|
|
676
|
+
{
|
|
677
|
+
className: orClasses3.swapDetailsLink,
|
|
678
|
+
href: row.href,
|
|
679
|
+
rel: "noreferrer",
|
|
680
|
+
target: "_blank"
|
|
681
|
+
},
|
|
682
|
+
row.hrefLabel ?? checkoutLabels2.viewOnExplorer
|
|
683
|
+
)
|
|
684
|
+
)
|
|
685
|
+
)
|
|
686
|
+
];
|
|
687
|
+
}
|
|
688
|
+
function TransactionDetailCopyButton(props) {
|
|
689
|
+
const [copied, setCopied] = useTransientValue(false);
|
|
690
|
+
const label = copied ? checkoutLabels2.copied : "Copy";
|
|
691
|
+
return React5.createElement(
|
|
692
|
+
"button",
|
|
693
|
+
{
|
|
694
|
+
className: orClasses3.detailCopy,
|
|
695
|
+
type: "button",
|
|
696
|
+
"aria-label": label,
|
|
697
|
+
title: label,
|
|
698
|
+
onClick: () => {
|
|
699
|
+
void copyText(props.value, props.clipboard).then(() => setCopied(true)).catch((error) => props.onError?.(error));
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
React5.createElement(ClipboardIcon)
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
|
|
700
706
|
// src/use-checkout.ts
|
|
701
707
|
import * as React6 from "react";
|
|
702
708
|
import {
|
|
@@ -935,8 +941,10 @@ import {
|
|
|
935
941
|
createMethodGridDisplay,
|
|
936
942
|
createPaymentWizardController,
|
|
937
943
|
createPaymentWizardModel,
|
|
944
|
+
createSwapDisplayModel as createSwapDisplayModel2,
|
|
938
945
|
createWizardRouteAssetDisplays,
|
|
939
946
|
createWizardRouteDisplays,
|
|
947
|
+
formatMethodNetworkDetail,
|
|
940
948
|
formatNetworkSummary,
|
|
941
949
|
getNetworkIcon,
|
|
942
950
|
getPaymentMethodIcon,
|
|
@@ -1199,16 +1207,17 @@ function ProviderTutorialModal(options) {
|
|
|
1199
1207
|
|
|
1200
1208
|
// src/swap.ts
|
|
1201
1209
|
import {
|
|
1210
|
+
checkoutLabels as checkoutLabels4,
|
|
1202
1211
|
createDetailExternalLink,
|
|
1212
|
+
createQrSvgController as createQrSvgController2,
|
|
1203
1213
|
createSwapDisplayModel,
|
|
1214
|
+
createSwapUnavailableModel,
|
|
1204
1215
|
createTransactionDetails,
|
|
1205
|
-
|
|
1216
|
+
currentCheckoutUrl,
|
|
1206
1217
|
getSwapRefundFormError,
|
|
1207
|
-
checkoutLabels as checkoutLabels4,
|
|
1208
|
-
createSwapUnavailableModel,
|
|
1209
|
-
swapOptionLimitMessage,
|
|
1210
1218
|
orClasses as orClasses5,
|
|
1211
|
-
selectCheckoutDisplayInvoice
|
|
1219
|
+
selectCheckoutDisplayInvoice,
|
|
1220
|
+
swapOptionLimitMessage
|
|
1212
1221
|
} from "@openreceive/browser/headless";
|
|
1213
1222
|
import * as React8 from "react";
|
|
1214
1223
|
function renderSwapActions(options) {
|
|
@@ -1339,6 +1348,25 @@ function renderSwapDepositPanel(options) {
|
|
|
1339
1348
|
display.providerStateDetail
|
|
1340
1349
|
)
|
|
1341
1350
|
);
|
|
1351
|
+
const refundHeading = React8.createElement(
|
|
1352
|
+
"div",
|
|
1353
|
+
{ className: orClasses5.swapRefundHeading, role: "alert" },
|
|
1354
|
+
renderAlertIcon("warning"),
|
|
1355
|
+
React8.createElement(
|
|
1356
|
+
"div",
|
|
1357
|
+
{ className: orClasses5.swapNetworkWarningContent },
|
|
1358
|
+
React8.createElement(
|
|
1359
|
+
"strong",
|
|
1360
|
+
{ className: orClasses5.swapHeadingTitle },
|
|
1361
|
+
display.providerStateLabel
|
|
1362
|
+
),
|
|
1363
|
+
React8.createElement(
|
|
1364
|
+
"span",
|
|
1365
|
+
{ className: orClasses5.swapHeadingDetail },
|
|
1366
|
+
display.providerStateDetail
|
|
1367
|
+
)
|
|
1368
|
+
)
|
|
1369
|
+
);
|
|
1342
1370
|
const waitingCard = (countdownLabel) => React8.createElement(WaitingState, {
|
|
1343
1371
|
waiting: true,
|
|
1344
1372
|
statusTitle: display.providerStateLabel,
|
|
@@ -1443,26 +1471,20 @@ function renderSwapDepositPanel(options) {
|
|
|
1443
1471
|
{
|
|
1444
1472
|
className: orClasses5.swapPanel
|
|
1445
1473
|
},
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
"p",
|
|
1450
|
-
{
|
|
1451
|
-
className: orClasses5.swapWarning
|
|
1452
|
-
},
|
|
1453
|
-
`Use a ${display.networkLabel} address you control. Do not paste the deposit address.`
|
|
1454
|
-
),
|
|
1474
|
+
refundHeading,
|
|
1475
|
+
renderSwapRefundReturnWarning(display, options),
|
|
1476
|
+
renderSwapAmountFacts(display),
|
|
1455
1477
|
React8.createElement(SwapRefundForm, {
|
|
1456
1478
|
attemptId: display.attemptId,
|
|
1457
1479
|
payInAsset: display.payInAsset,
|
|
1458
1480
|
networkLabel: display.networkLabel,
|
|
1481
|
+
...display.refundReason === void 0 ? {} : { refundReason: display.refundReason },
|
|
1459
1482
|
submittedRefundAddress: display.refundAddress,
|
|
1460
1483
|
refundAllowed: display.refundAllowed,
|
|
1461
1484
|
onRefund: options.onRefund,
|
|
1462
1485
|
onError: options.onError
|
|
1463
1486
|
}),
|
|
1464
|
-
renderSwapSupportDetails(display, options)
|
|
1465
|
-
renderSwapRefundReturnWarning(display)
|
|
1487
|
+
renderSwapSupportDetails(display, options)
|
|
1466
1488
|
);
|
|
1467
1489
|
}
|
|
1468
1490
|
if (display.state === "refund_pending" || display.state === "refunded") {
|
|
@@ -1471,8 +1493,9 @@ function renderSwapDepositPanel(options) {
|
|
|
1471
1493
|
{
|
|
1472
1494
|
className: orClasses5.swapPanel
|
|
1473
1495
|
},
|
|
1474
|
-
|
|
1475
|
-
|
|
1496
|
+
refundHeading,
|
|
1497
|
+
renderSwapRefundReturnWarning(display, options),
|
|
1498
|
+
renderSwapAmountFacts(display),
|
|
1476
1499
|
React8.createElement(
|
|
1477
1500
|
"dl",
|
|
1478
1501
|
{
|
|
@@ -1489,8 +1512,7 @@ function renderSwapDepositPanel(options) {
|
|
|
1489
1512
|
payInAsset: display.payInAsset
|
|
1490
1513
|
})
|
|
1491
1514
|
),
|
|
1492
|
-
renderSwapSupportDetails(display, options)
|
|
1493
|
-
renderSwapRefundReturnWarning(display)
|
|
1515
|
+
renderSwapSupportDetails(display, options)
|
|
1494
1516
|
);
|
|
1495
1517
|
}
|
|
1496
1518
|
if (display.state === "deposit") {
|
|
@@ -1514,11 +1536,15 @@ function renderSwapDepositPanel(options) {
|
|
|
1514
1536
|
{
|
|
1515
1537
|
className: orClasses5.swapDepositLayout
|
|
1516
1538
|
},
|
|
1517
|
-
React8.createElement(
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1539
|
+
React8.createElement(
|
|
1540
|
+
"div",
|
|
1541
|
+
{ className: orClasses5.swapQrFrame },
|
|
1542
|
+
React8.createElement(SwapPayloadQRCode, {
|
|
1543
|
+
payload: display.qrPayload,
|
|
1544
|
+
encoder: options.encoder,
|
|
1545
|
+
onError: options.onError
|
|
1546
|
+
})
|
|
1547
|
+
),
|
|
1522
1548
|
React8.createElement(
|
|
1523
1549
|
"div",
|
|
1524
1550
|
{
|
|
@@ -1554,9 +1580,10 @@ function renderSwapDepositPanel(options) {
|
|
|
1554
1580
|
React8.createElement(
|
|
1555
1581
|
"p",
|
|
1556
1582
|
{ className: orClasses5.swapWarning },
|
|
1557
|
-
checkoutLabels4.
|
|
1583
|
+
checkoutLabels4.supportReviewFacts
|
|
1558
1584
|
),
|
|
1559
|
-
|
|
1585
|
+
renderSwapAmountFacts(display),
|
|
1586
|
+
renderSwapSupportDetails(display, options, { open: true }),
|
|
1560
1587
|
backButton
|
|
1561
1588
|
);
|
|
1562
1589
|
}
|
|
@@ -1610,26 +1637,45 @@ function renderSwapNetworkWarning(display) {
|
|
|
1610
1637
|
)
|
|
1611
1638
|
);
|
|
1612
1639
|
}
|
|
1613
|
-
function
|
|
1640
|
+
function renderSwapAmountFacts(display) {
|
|
1614
1641
|
const rows = [
|
|
1615
|
-
...display.depositReceivedAmount === void 0 ? [] :
|
|
1616
|
-
"Amount received",
|
|
1617
|
-
`${display.
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
...display.depositReceivedAmount === void 0 ? [] : renderSwapCopyRow(
|
|
1621
|
-
"Amount required",
|
|
1622
|
-
`${display.depositAmount} ${display.assetLabel}`,
|
|
1623
|
-
options
|
|
1624
|
-
),
|
|
1625
|
-
...display.refundAmount === void 0 ? [] : renderSwapCopyRow(
|
|
1626
|
-
"Estimated refund",
|
|
1627
|
-
`${display.refundAmount} ${display.assetLabel}`,
|
|
1628
|
-
options
|
|
1629
|
-
)
|
|
1642
|
+
...display.depositReceivedAmount === void 0 ? [] : [
|
|
1643
|
+
["Amount received", `${display.depositReceivedAmount} ${display.assetLabel}`],
|
|
1644
|
+
["Amount required", `${display.depositAmount} ${display.assetLabel}`]
|
|
1645
|
+
],
|
|
1646
|
+
...display.refundAmount === void 0 ? [] : [["Estimated refund", `${display.refundAmount} ${display.assetLabel}`]]
|
|
1630
1647
|
];
|
|
1631
1648
|
if (rows.length === 0) return null;
|
|
1632
|
-
return React8.createElement(
|
|
1649
|
+
return React8.createElement(
|
|
1650
|
+
"dl",
|
|
1651
|
+
{ className: orClasses5.swapFacts },
|
|
1652
|
+
rows.map(
|
|
1653
|
+
([label, value]) => React8.createElement(
|
|
1654
|
+
"div",
|
|
1655
|
+
{ key: label, className: orClasses5.swapFactsRow },
|
|
1656
|
+
React8.createElement("dt", { className: orClasses5.swapFactsLabel }, label),
|
|
1657
|
+
React8.createElement("dd", { className: orClasses5.swapFactsValue }, value)
|
|
1658
|
+
)
|
|
1659
|
+
)
|
|
1660
|
+
);
|
|
1661
|
+
}
|
|
1662
|
+
function renderAlertIcon(kind) {
|
|
1663
|
+
return React8.createElement(
|
|
1664
|
+
"svg",
|
|
1665
|
+
{
|
|
1666
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1667
|
+
fill: "none",
|
|
1668
|
+
viewBox: "0 0 24 24",
|
|
1669
|
+
className: orClasses5.swapNetworkWarningIcon,
|
|
1670
|
+
"aria-hidden": "true"
|
|
1671
|
+
},
|
|
1672
|
+
React8.createElement("path", {
|
|
1673
|
+
strokeLinecap: "round",
|
|
1674
|
+
strokeLinejoin: "round",
|
|
1675
|
+
strokeWidth: 2,
|
|
1676
|
+
d: kind === "warning" ? "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" : "M17 3H7a2 2 0 00-2 2v16l7-3.5L19 21V5a2 2 0 00-2-2z"
|
|
1677
|
+
})
|
|
1678
|
+
);
|
|
1633
1679
|
}
|
|
1634
1680
|
function renderSwapFeeBreakdown(breakdown) {
|
|
1635
1681
|
if (breakdown === void 0) return null;
|
|
@@ -1728,7 +1774,7 @@ function SwapCopyButton(props) {
|
|
|
1728
1774
|
React8.createElement(ClipboardIcon)
|
|
1729
1775
|
);
|
|
1730
1776
|
}
|
|
1731
|
-
function renderSwapSupportDetails(display, options) {
|
|
1777
|
+
function renderSwapSupportDetails(display, options, view = {}) {
|
|
1732
1778
|
const rowOptions = { ...options, payInAsset: display.payInAsset };
|
|
1733
1779
|
const rows = [
|
|
1734
1780
|
...display.depositTxId === void 0 ? [] : renderSwapCopyRow("Deposit transaction", display.depositTxId, rowOptions),
|
|
@@ -1740,7 +1786,8 @@ function renderSwapSupportDetails(display, options) {
|
|
|
1740
1786
|
return React8.createElement(
|
|
1741
1787
|
"details",
|
|
1742
1788
|
{
|
|
1743
|
-
className: orClasses5.swapSupport
|
|
1789
|
+
className: orClasses5.swapSupport,
|
|
1790
|
+
...view.open === true ? { open: true } : {}
|
|
1744
1791
|
},
|
|
1745
1792
|
React8.createElement("summary", { className: orClasses5.swapSupportTitle }, "Payment details"),
|
|
1746
1793
|
React8.createElement(
|
|
@@ -1750,13 +1797,57 @@ function renderSwapSupportDetails(display, options) {
|
|
|
1750
1797
|
)
|
|
1751
1798
|
);
|
|
1752
1799
|
}
|
|
1753
|
-
function renderSwapRefundReturnWarning(display) {
|
|
1800
|
+
function renderSwapRefundReturnWarning(display, options) {
|
|
1801
|
+
const url = display.resumable ? currentCheckoutUrl() : void 0;
|
|
1754
1802
|
return React8.createElement(
|
|
1755
|
-
"
|
|
1756
|
-
{
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1803
|
+
"div",
|
|
1804
|
+
{ className: orClasses5.swapRefundReturn },
|
|
1805
|
+
renderAlertIcon("bookmark"),
|
|
1806
|
+
React8.createElement(
|
|
1807
|
+
"div",
|
|
1808
|
+
{ className: orClasses5.swapNetworkWarningContent },
|
|
1809
|
+
React8.createElement(
|
|
1810
|
+
"p",
|
|
1811
|
+
{ className: orClasses5.swapRefundReturnTitle },
|
|
1812
|
+
checkoutLabels4.refundReturnTitle
|
|
1813
|
+
),
|
|
1814
|
+
React8.createElement(
|
|
1815
|
+
"p",
|
|
1816
|
+
{ className: orClasses5.swapRefundReturnBody },
|
|
1817
|
+
display.refundReturnLabel
|
|
1818
|
+
),
|
|
1819
|
+
url === void 0 ? null : React8.createElement(
|
|
1820
|
+
"dl",
|
|
1821
|
+
{ className: orClasses5.swapDetails },
|
|
1822
|
+
...renderSwapCopyRow(checkoutLabels4.refundReturnUrlLabel, url, {
|
|
1823
|
+
...options,
|
|
1824
|
+
selectable: true
|
|
1825
|
+
})
|
|
1826
|
+
)
|
|
1827
|
+
)
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1830
|
+
function renderKeepOrderNote(options) {
|
|
1831
|
+
if (options.resumable !== true) return null;
|
|
1832
|
+
const reference = options.reference ?? "";
|
|
1833
|
+
const url = currentCheckoutUrl();
|
|
1834
|
+
if (reference.length === 0 && url === void 0) return null;
|
|
1835
|
+
const rowOptions = { ...options, selectable: true };
|
|
1836
|
+
return React8.createElement(
|
|
1837
|
+
"div",
|
|
1838
|
+
{ className: orClasses5.keepOrder },
|
|
1839
|
+
React8.createElement(
|
|
1840
|
+
"p",
|
|
1841
|
+
{ className: orClasses5.swapSectionTitle },
|
|
1842
|
+
checkoutLabels4.keepOrderTitle
|
|
1843
|
+
),
|
|
1844
|
+
React8.createElement("p", { className: orClasses5.keepOrderBody }, checkoutLabels4.keepOrderBody),
|
|
1845
|
+
React8.createElement(
|
|
1846
|
+
"dl",
|
|
1847
|
+
{ className: orClasses5.swapDetails },
|
|
1848
|
+
...reference.length === 0 ? [] : renderSwapCopyRow(checkoutLabels4.keepOrderIdLabel, reference, rowOptions),
|
|
1849
|
+
...url === void 0 ? [] : renderSwapCopyRow(checkoutLabels4.keepOrderUrlLabel, url, rowOptions)
|
|
1850
|
+
)
|
|
1760
1851
|
);
|
|
1761
1852
|
}
|
|
1762
1853
|
var REFUND_ADDRESS_DRAFT_LIMIT = 8;
|
|
@@ -1799,10 +1890,30 @@ function SwapRefundForm(props) {
|
|
|
1799
1890
|
void props.onRefund(props.attemptId, address, confirm).catch(props.onError).finally(() => setSubmitting(false));
|
|
1800
1891
|
}
|
|
1801
1892
|
},
|
|
1893
|
+
// The form says what it is and why it is here before it asks for anything:
|
|
1894
|
+
// a bare input under a red banner is a payer guessing what to type.
|
|
1895
|
+
React8.createElement(
|
|
1896
|
+
"p",
|
|
1897
|
+
{ className: orClasses5.swapSectionTitle },
|
|
1898
|
+
checkoutLabels4.refundSectionTitle
|
|
1899
|
+
),
|
|
1900
|
+
props.refundReason === void 0 ? null : React8.createElement(
|
|
1901
|
+
"p",
|
|
1902
|
+
{ className: orClasses5.swapRefundReason },
|
|
1903
|
+
checkoutLabels4.refundReasonLabel.replace(
|
|
1904
|
+
"{reason}",
|
|
1905
|
+
props.refundReason.replace(/_/g, " ")
|
|
1906
|
+
)
|
|
1907
|
+
),
|
|
1908
|
+
React8.createElement(
|
|
1909
|
+
"p",
|
|
1910
|
+
{ className: orClasses5.swapRefundInstruction },
|
|
1911
|
+
checkoutLabels4.refundAddressOwnership.replace("{network}", props.networkLabel)
|
|
1912
|
+
),
|
|
1802
1913
|
props.submittedRefundAddress === void 0 ? null : React8.createElement(
|
|
1803
1914
|
"p",
|
|
1804
1915
|
{
|
|
1805
|
-
className: orClasses5.
|
|
1916
|
+
className: orClasses5.swapRefundInstruction
|
|
1806
1917
|
},
|
|
1807
1918
|
checkoutLabels4.confirmRefundTo.replace("{address}", props.submittedRefundAddress)
|
|
1808
1919
|
),
|
|
@@ -2007,6 +2118,18 @@ function PaymentWizard(props) {
|
|
|
2007
2118
|
stickySwapInvoiceRef.current = void 0;
|
|
2008
2119
|
}
|
|
2009
2120
|
const activeSwapForAsset = selectedSwapAsset === null ? void 0 : currentSwapInvoice !== void 0 && currentSwapInvoice.swap?.pay_in_asset === selectedSwapAsset ? currentSwapInvoice : stickySwapInvoiceRef.current?.swap?.pay_in_asset === selectedSwapAsset ? stickySwapInvoiceRef.current : void 0;
|
|
2121
|
+
const resumeAdoptedRef = React9.useRef(false);
|
|
2122
|
+
React9.useEffect(() => {
|
|
2123
|
+
if (resumeAdoptedRef.current) return;
|
|
2124
|
+
if (selectedSwapAsset !== null) {
|
|
2125
|
+
resumeAdoptedRef.current = true;
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
const payInAsset = currentSwapInvoice?.swap?.pay_in_asset;
|
|
2129
|
+
if (payInAsset === void 0) return;
|
|
2130
|
+
resumeAdoptedRef.current = true;
|
|
2131
|
+
setSelectedSwapAsset(payInAsset);
|
|
2132
|
+
}, [currentSwapInvoice, selectedSwapAsset]);
|
|
2010
2133
|
React9.useEffect(() => {
|
|
2011
2134
|
if (selectedSwapAsset === null) return;
|
|
2012
2135
|
if (props.prefix === void 0) return;
|
|
@@ -2018,6 +2141,18 @@ function PaymentWizard(props) {
|
|
|
2018
2141
|
const selectedSwapOption = selectedSwapAsset === null ? void 0 : swapAssetOptions.find((option) => option.pay_in_asset === selectedSwapAsset) ?? session.swapQuotes[selectedSwapAsset];
|
|
2019
2142
|
const selectedSwapQuote = selectedSwapAsset === null ? void 0 : session.swapQuotes[selectedSwapAsset];
|
|
2020
2143
|
const selectedSwapLabel = selectedSwapOption?.label ?? "this coin";
|
|
2144
|
+
const activeSwapState = activeSwapForAsset === void 0 ? void 0 : createSwapDisplayModel2(activeSwapForAsset, {
|
|
2145
|
+
...now === void 0 ? {} : { now },
|
|
2146
|
+
...props.resumable === void 0 ? {} : { resumable: props.resumable }
|
|
2147
|
+
})?.state;
|
|
2148
|
+
const refundOwed = activeSwapState === "refund_required";
|
|
2149
|
+
const refundStage = activeSwapState?.startsWith("refund") ?? false;
|
|
2150
|
+
const keepOrderNote = renderKeepOrderNote({
|
|
2151
|
+
...checkout?.reference === void 0 ? {} : { reference: checkout.reference },
|
|
2152
|
+
...props.resumable === void 0 ? {} : { resumable: props.resumable },
|
|
2153
|
+
...props.clipboard === void 0 ? {} : { clipboard: props.clipboard },
|
|
2154
|
+
...props.onError === void 0 ? {} : { onError: props.onError }
|
|
2155
|
+
});
|
|
2021
2156
|
if (selectedSwapAsset !== null) {
|
|
2022
2157
|
return React9.createElement(
|
|
2023
2158
|
"div",
|
|
@@ -2027,7 +2162,7 @@ function PaymentWizard(props) {
|
|
|
2027
2162
|
React9.createElement(
|
|
2028
2163
|
"div",
|
|
2029
2164
|
{ className: orClasses6.wizardBody },
|
|
2030
|
-
renderWizardBackBreadcrumb(
|
|
2165
|
+
refundOwed ? null : renderWizardBackBreadcrumb(
|
|
2031
2166
|
selectedSwapOption === void 0 ? selectedSwapLabel : `${selectedSwapOption.label} \xB7 ${selectedSwapOption.network_label}`,
|
|
2032
2167
|
clearSwapFocus
|
|
2033
2168
|
),
|
|
@@ -2055,7 +2190,8 @@ function PaymentWizard(props) {
|
|
|
2055
2190
|
void props.onRequestLightning?.();
|
|
2056
2191
|
}
|
|
2057
2192
|
}) : selectedSwapQuote !== void 0 && !selectedSwapQuote.available ? renderSwapUnavailable(selectedSwapQuote, checkout) : renderSwapPreparing(selectedSwapLabel)
|
|
2058
|
-
)
|
|
2193
|
+
),
|
|
2194
|
+
refundStage ? null : keepOrderNote
|
|
2059
2195
|
)
|
|
2060
2196
|
);
|
|
2061
2197
|
}
|
|
@@ -2118,6 +2254,13 @@ function PaymentWizard(props) {
|
|
|
2118
2254
|
onContinueSwap: selectSwapAsset,
|
|
2119
2255
|
...resolveAssetUrl === void 0 ? {} : { resolveAssetUrl }
|
|
2120
2256
|
}) : null,
|
|
2257
|
+
// On the grid the note is a section of its own, under the tiles: there is no
|
|
2258
|
+
// body to put it in until a method is chosen.
|
|
2259
|
+
selection.selectedMethod === null && keepOrderNote !== null ? React9.createElement(
|
|
2260
|
+
"div",
|
|
2261
|
+
{ key: "keep-order", className: orClasses6.wizardBody },
|
|
2262
|
+
keepOrderNote
|
|
2263
|
+
) : null,
|
|
2121
2264
|
selection.selectedMethod === null ? null : React9.createElement(
|
|
2122
2265
|
"div",
|
|
2123
2266
|
{ className: orClasses6.wizardBody },
|
|
@@ -2246,7 +2389,8 @@ function PaymentWizard(props) {
|
|
|
2246
2389
|
) : null
|
|
2247
2390
|
);
|
|
2248
2391
|
})
|
|
2249
|
-
)
|
|
2392
|
+
),
|
|
2393
|
+
keepOrderNote
|
|
2250
2394
|
),
|
|
2251
2395
|
activeTutorialProvider === void 0 || activeTutorial === null ? null : React9.createElement(ProviderTutorialModal, {
|
|
2252
2396
|
key: "provider-tutorial",
|
|
@@ -2482,7 +2626,15 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2482
2626
|
React9.createElement(
|
|
2483
2627
|
"span",
|
|
2484
2628
|
{ className: orClasses6.methodTitleWrap },
|
|
2485
|
-
React9.createElement("span", { className: orClasses6.methodTitle }, method.title)
|
|
2629
|
+
React9.createElement("span", { className: orClasses6.methodTitle }, method.title),
|
|
2630
|
+
// The tile's own description. A grid of five names is a grid of
|
|
2631
|
+
// five questions; `paymentMethods` has carried the answer all
|
|
2632
|
+
// along and only the mobile layout was printing it.
|
|
2633
|
+
React9.createElement(
|
|
2634
|
+
"span",
|
|
2635
|
+
{ className: orClasses6.methodTileDetail },
|
|
2636
|
+
method.detail
|
|
2637
|
+
)
|
|
2486
2638
|
)
|
|
2487
2639
|
);
|
|
2488
2640
|
}
|
|
@@ -2492,7 +2644,6 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2492
2644
|
selected,
|
|
2493
2645
|
multiNetwork,
|
|
2494
2646
|
displayOption,
|
|
2495
|
-
selectedOption,
|
|
2496
2647
|
starting,
|
|
2497
2648
|
disabled,
|
|
2498
2649
|
accent,
|
|
@@ -2542,11 +2693,11 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2542
2693
|
"span",
|
|
2543
2694
|
{ className: orClasses6.methodTitleWrap },
|
|
2544
2695
|
React9.createElement("span", { className: orClasses6.methodTitle }, group.label),
|
|
2545
|
-
|
|
2696
|
+
React9.createElement(
|
|
2546
2697
|
"span",
|
|
2547
|
-
{ className: orClasses6.
|
|
2548
|
-
|
|
2549
|
-
)
|
|
2698
|
+
{ className: orClasses6.methodTileDetail },
|
|
2699
|
+
formatMethodNetworkDetail(group.options)
|
|
2700
|
+
)
|
|
2550
2701
|
)
|
|
2551
2702
|
),
|
|
2552
2703
|
disabled && limitMessage !== void 0 ? React9.createElement("span", { className: orClasses6.methodLimitHint }, limitMessage) : null,
|
|
@@ -2726,7 +2877,8 @@ function Checkout(props) {
|
|
|
2726
2877
|
metadata: props.metadata,
|
|
2727
2878
|
syncUrl: props.syncUrl,
|
|
2728
2879
|
resumePathPrefix: props.resumePathPrefix,
|
|
2729
|
-
routeReference: props.routeReference
|
|
2880
|
+
routeReference: props.routeReference,
|
|
2881
|
+
resumePaymentHash: props.resumePaymentHash
|
|
2730
2882
|
});
|
|
2731
2883
|
const { checkout } = props;
|
|
2732
2884
|
if (checkout !== void 0) {
|
|
@@ -2769,7 +2921,8 @@ function CheckoutCreate(props) {
|
|
|
2769
2921
|
classNames,
|
|
2770
2922
|
syncUrl = false,
|
|
2771
2923
|
resumePathPrefix = "/checkout",
|
|
2772
|
-
routeReference
|
|
2924
|
+
routeReference,
|
|
2925
|
+
resumePaymentHash
|
|
2773
2926
|
} = props;
|
|
2774
2927
|
const [created, setCreated] = React10.useState({ status: "pending" });
|
|
2775
2928
|
const [attempt, setAttempt] = React10.useState(0);
|
|
@@ -2810,7 +2963,15 @@ function CheckoutCreate(props) {
|
|
|
2810
2963
|
prefix: resolvedPrefix,
|
|
2811
2964
|
reference,
|
|
2812
2965
|
...createFetchRef.current === void 0 ? {} : { fetch: createFetchRef.current }
|
|
2813
|
-
}).then(
|
|
2966
|
+
}).then(
|
|
2967
|
+
(checkout) => resumePaymentHash === void 0 ? checkout : resumeSwapAttempt({
|
|
2968
|
+
fetch: createFetchRef.current ?? globalThis.fetch,
|
|
2969
|
+
prefix: resolvedPrefix,
|
|
2970
|
+
reference,
|
|
2971
|
+
paymentHash: resumePaymentHash,
|
|
2972
|
+
snapshot: checkout
|
|
2973
|
+
})
|
|
2974
|
+
).then((checkout) => {
|
|
2814
2975
|
if (!cancelled) setCreated({ status: "ready", checkout });
|
|
2815
2976
|
}).catch((error) => {
|
|
2816
2977
|
if (cancelled) return;
|
|
@@ -2823,7 +2984,7 @@ function CheckoutCreate(props) {
|
|
|
2823
2984
|
return () => {
|
|
2824
2985
|
cancelled = true;
|
|
2825
2986
|
};
|
|
2826
|
-
}, [reference, resolvedPrefix, attempt]);
|
|
2987
|
+
}, [reference, resolvedPrefix, resumePaymentHash, attempt]);
|
|
2827
2988
|
const onSwapStarted = React10.useCallback(
|
|
2828
2989
|
(invoice) => {
|
|
2829
2990
|
setCreated((current) => {
|
|
@@ -2908,6 +3069,9 @@ function CheckoutView(props) {
|
|
|
2908
3069
|
syncUrl,
|
|
2909
3070
|
resumePathPrefix: _resumePathPrefix,
|
|
2910
3071
|
routeReference,
|
|
3072
|
+
// Consumed by CheckoutCreate before the view exists; destructured out here
|
|
3073
|
+
// so it never reaches the rendered <section> as an attribute.
|
|
3074
|
+
resumePaymentHash: _resumePaymentHash,
|
|
2911
3075
|
resumable,
|
|
2912
3076
|
onRequestLightning,
|
|
2913
3077
|
onSwapStarted,
|
|
@@ -2927,6 +3091,7 @@ function CheckoutView(props) {
|
|
|
2927
3091
|
pollIntervalMs,
|
|
2928
3092
|
paymentWizard = true,
|
|
2929
3093
|
themeToggle = true,
|
|
3094
|
+
theme: lockedTheme,
|
|
2930
3095
|
defaultTheme,
|
|
2931
3096
|
storageKey,
|
|
2932
3097
|
components,
|
|
@@ -2952,9 +3117,11 @@ function CheckoutView(props) {
|
|
|
2952
3117
|
});
|
|
2953
3118
|
const theme = useTheme({
|
|
2954
3119
|
defaultTheme,
|
|
2955
|
-
storageKey
|
|
3120
|
+
storageKey,
|
|
3121
|
+
theme: lockedTheme
|
|
2956
3122
|
});
|
|
2957
|
-
const
|
|
3123
|
+
const stampsTheme = !theme.fromScope;
|
|
3124
|
+
const ownsTheme = themeToggle && !theme.fromScope && lockedTheme === void 0;
|
|
2958
3125
|
const [swapFocused, setSwapFocused] = React10.useState(false);
|
|
2959
3126
|
const QRCodeComponent = components?.QRCode ?? QRCode;
|
|
2960
3127
|
const InvoiceSummaryComponent = components?.InvoiceSummary ?? InvoiceSummary;
|
|
@@ -3001,206 +3168,207 @@ function CheckoutView(props) {
|
|
|
3001
3168
|
className: joinClassNames(className, orClasses7.root, classNames?.root),
|
|
3002
3169
|
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.root]: "",
|
|
3003
3170
|
// Under ThemeScope, inherit data-theme from the page. Standalone Checkout owns it.
|
|
3004
|
-
...
|
|
3171
|
+
...stampsTheme ? theme.attributes : {}
|
|
3005
3172
|
},
|
|
3006
|
-
|
|
3007
|
-
//
|
|
3008
|
-
// the
|
|
3009
|
-
//
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
className: orClasses7.creating
|
|
3035
|
-
},
|
|
3036
|
-
React10.createElement("span", {
|
|
3037
|
-
className: orClasses7.spinner,
|
|
3038
|
-
"aria-hidden": "true"
|
|
3039
|
-
}),
|
|
3040
|
-
React10.createElement("p", null, checkoutLabels6.preparingPayment)
|
|
3041
|
-
) : null,
|
|
3042
|
-
hideLightning ? null : React10.createElement(
|
|
3043
|
-
"div",
|
|
3044
|
-
{
|
|
3045
|
-
key: "payment-layout",
|
|
3046
|
-
className: expired || settled ? orClasses7.paymentLayoutExpired : orClasses7.paymentLayout
|
|
3047
|
-
},
|
|
3048
|
-
lightningPane,
|
|
3049
|
-
React10.createElement(
|
|
3173
|
+
[
|
|
3174
|
+
// Order context from the host, composed ABOVE the shipped payment UI —
|
|
3175
|
+
// the same position as the custom element's `order` slot. Children never
|
|
3176
|
+
// replace the payment UI; a host that wants its own checkout builds on
|
|
3177
|
+
// useCheckout / @openreceive/browser/headless instead.
|
|
3178
|
+
customChildren === void 0 ? null : React10.createElement(React10.Fragment, { key: "order-children" }, customChildren),
|
|
3179
|
+
...[
|
|
3180
|
+
// Above the amount and OUTSIDE the Lightning pane, which drops out on
|
|
3181
|
+
// the swap deposit panel, on expiry and on the receipt — the payer
|
|
3182
|
+
// needs to know what they are buying on all four screens.
|
|
3183
|
+
checkoutModel.checkout.description === void 0 || checkoutModel.checkout.description === "" ? null : React10.createElement(
|
|
3184
|
+
"p",
|
|
3185
|
+
{
|
|
3186
|
+
key: "order-description",
|
|
3187
|
+
className: joinClassNames(orClasses7.orderDescription, classNames?.orderDescription),
|
|
3188
|
+
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.orderDescription]: ""
|
|
3189
|
+
},
|
|
3190
|
+
checkoutModel.checkout.description
|
|
3191
|
+
),
|
|
3192
|
+
ownsTheme ? React10.createElement(ThemeToggle, {
|
|
3193
|
+
key: "theme",
|
|
3194
|
+
className: classNames?.themeToggle,
|
|
3195
|
+
theme: theme.theme,
|
|
3196
|
+
resolvedTheme: theme.resolvedTheme,
|
|
3197
|
+
onThemeChange: theme.setTheme,
|
|
3198
|
+
ButtonComponent
|
|
3199
|
+
}) : null,
|
|
3200
|
+
mintingLightning ? React10.createElement(
|
|
3050
3201
|
"div",
|
|
3051
3202
|
{
|
|
3052
|
-
key: "
|
|
3053
|
-
className: orClasses7.
|
|
3203
|
+
key: "minting-lightning",
|
|
3204
|
+
className: orClasses7.creating
|
|
3054
3205
|
},
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
key: "invoice-title",
|
|
3059
|
-
className: joinClassNames(
|
|
3060
|
-
orClasses7.invoiceTitle,
|
|
3061
|
-
classNames?.invoiceTitle
|
|
3062
|
-
)
|
|
3063
|
-
},
|
|
3064
|
-
checkoutLabels6.bitcoinLightningInvoice
|
|
3065
|
-
),
|
|
3066
|
-
React10.createElement(WaitingState, {
|
|
3067
|
-
key: "waiting",
|
|
3068
|
-
waiting: checkoutModel.waiting,
|
|
3069
|
-
statusTitle: checkoutModel.statusTitle,
|
|
3070
|
-
statusDetail: checkoutModel.statusDetail,
|
|
3071
|
-
settled,
|
|
3072
|
-
className: classNames?.waiting
|
|
3206
|
+
React10.createElement("span", {
|
|
3207
|
+
className: orClasses7.spinner,
|
|
3208
|
+
"aria-hidden": "true"
|
|
3073
3209
|
}),
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
{ className: orClasses7.countdownStrong },
|
|
3085
|
-
checkoutModel.countdownLabel
|
|
3086
|
-
)
|
|
3087
|
-
),
|
|
3088
|
-
showSummaryMeta ? React10.createElement(InvoiceSummaryComponent, {
|
|
3089
|
-
key: "summary",
|
|
3090
|
-
status: checkoutModel.status,
|
|
3091
|
-
PaymentStateComponent,
|
|
3092
|
-
className: classNames?.summary,
|
|
3093
|
-
classNames
|
|
3094
|
-
}) : null,
|
|
3095
|
-
settled ? React10.createElement(TransactionDetails, {
|
|
3096
|
-
key: "transaction-details",
|
|
3097
|
-
// The model IS the checkout state, so the panel reads
|
|
3098
|
-
// the same derivation the rest of the screen does. It
|
|
3099
|
-
// used to re-flatten the snapshot separately, which
|
|
3100
|
-
// reported the displayed ATTEMPT's transaction /
|
|
3101
|
-
// workflow state on a checkout the state already knows
|
|
3102
|
-
// is paid.
|
|
3103
|
-
//
|
|
3104
|
-
// The SAME panel the swap flow renders one screen
|
|
3105
|
-
// earlier. A payer's whole evidence that they paid is a
|
|
3106
|
-
// payment hash and, on a swap, a deposit txid — so the
|
|
3107
|
-
// most keep-worthy screen gets copy buttons and
|
|
3108
|
-
// explorer links, not un-copyable text. No
|
|
3109
|
-
// `decodeLinkUrl` is passed, so the bolt11 never
|
|
3110
|
-
// reaches a third party.
|
|
3111
|
-
state: checkoutModel,
|
|
3112
|
-
className: classNames?.details,
|
|
3113
|
-
onError
|
|
3114
|
-
}) : expired ? React10.createElement(
|
|
3210
|
+
React10.createElement("p", null, checkoutLabels6.preparingPayment)
|
|
3211
|
+
) : null,
|
|
3212
|
+
hideLightning ? null : React10.createElement(
|
|
3213
|
+
"div",
|
|
3214
|
+
{
|
|
3215
|
+
key: "payment-layout",
|
|
3216
|
+
className: expired || settled ? orClasses7.paymentLayoutExpired : orClasses7.paymentLayout
|
|
3217
|
+
},
|
|
3218
|
+
lightningPane,
|
|
3219
|
+
React10.createElement(
|
|
3115
3220
|
"div",
|
|
3116
3221
|
{
|
|
3117
|
-
key: "
|
|
3118
|
-
className:
|
|
3119
|
-
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.actions]: ""
|
|
3222
|
+
key: "payment-info",
|
|
3223
|
+
className: orClasses7.paymentInfo
|
|
3120
3224
|
},
|
|
3121
|
-
React10.createElement(
|
|
3122
|
-
|
|
3225
|
+
expired || settled ? null : React10.createElement(
|
|
3226
|
+
"p",
|
|
3123
3227
|
{
|
|
3124
|
-
|
|
3125
|
-
className: orClasses7.
|
|
3126
|
-
onClick: startOver
|
|
3228
|
+
key: "invoice-title",
|
|
3229
|
+
className: joinClassNames(orClasses7.invoiceTitle, classNames?.invoiceTitle)
|
|
3127
3230
|
},
|
|
3128
|
-
checkoutLabels6.
|
|
3129
|
-
)
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
React10.createElement(CopyButton, {
|
|
3138
|
-
key: "copy-invoice",
|
|
3139
|
-
invoice: checkoutModel.invoice,
|
|
3140
|
-
copyInvoice: checkoutModel.copyInvoice,
|
|
3141
|
-
onError,
|
|
3142
|
-
logger,
|
|
3143
|
-
ButtonComponent,
|
|
3144
|
-
className: classNames?.copyButton
|
|
3145
|
-
}),
|
|
3146
|
-
// Opt-in slot: the default checkout ships no wallet button, so a
|
|
3147
|
-
// desktop payer is never sent to a handler that does not exist.
|
|
3148
|
-
OpenWalletButtonComponent === void 0 ? null : React10.createElement(OpenWalletButtonComponent, {
|
|
3149
|
-
key: "open-wallet",
|
|
3150
|
-
invoice: checkoutModel.invoice,
|
|
3151
|
-
openWallet: checkoutModel.openWallet,
|
|
3152
|
-
onError,
|
|
3153
|
-
logger,
|
|
3154
|
-
ButtonComponent,
|
|
3155
|
-
className: classNames?.openWalletButton
|
|
3231
|
+
checkoutLabels6.bitcoinLightningInvoice
|
|
3232
|
+
),
|
|
3233
|
+
React10.createElement(WaitingState, {
|
|
3234
|
+
key: "waiting",
|
|
3235
|
+
waiting: checkoutModel.waiting,
|
|
3236
|
+
statusTitle: checkoutModel.statusTitle,
|
|
3237
|
+
statusDetail: checkoutModel.statusDetail,
|
|
3238
|
+
settled,
|
|
3239
|
+
className: classNames?.waiting
|
|
3156
3240
|
}),
|
|
3157
|
-
|
|
3158
|
-
"
|
|
3241
|
+
checkoutModel.countdownLabel === void 0 ? null : React10.createElement(
|
|
3242
|
+
"div",
|
|
3243
|
+
{
|
|
3244
|
+
key: "countdown",
|
|
3245
|
+
className: joinClassNames(orClasses7.countdown, classNames?.countdown)
|
|
3246
|
+
},
|
|
3247
|
+
checkoutModel.countdownPrefix,
|
|
3248
|
+
" ",
|
|
3249
|
+
React10.createElement(
|
|
3250
|
+
"strong",
|
|
3251
|
+
{ className: orClasses7.countdownStrong },
|
|
3252
|
+
checkoutModel.countdownLabel
|
|
3253
|
+
)
|
|
3254
|
+
),
|
|
3255
|
+
showSummaryMeta ? React10.createElement(InvoiceSummaryComponent, {
|
|
3256
|
+
key: "summary",
|
|
3257
|
+
status: checkoutModel.status,
|
|
3258
|
+
PaymentStateComponent,
|
|
3259
|
+
className: classNames?.summary,
|
|
3260
|
+
classNames
|
|
3261
|
+
}) : null,
|
|
3262
|
+
settled ? React10.createElement(TransactionDetails, {
|
|
3263
|
+
key: "transaction-details",
|
|
3264
|
+
// The model IS the checkout state, so the panel reads
|
|
3265
|
+
// the same derivation the rest of the screen does. It
|
|
3266
|
+
// used to re-flatten the snapshot separately, which
|
|
3267
|
+
// reported the displayed ATTEMPT's transaction /
|
|
3268
|
+
// workflow state on a checkout the state already knows
|
|
3269
|
+
// is paid.
|
|
3270
|
+
//
|
|
3271
|
+
// The SAME panel the swap flow renders one screen
|
|
3272
|
+
// earlier. A payer's whole evidence that they paid is a
|
|
3273
|
+
// payment hash and, on a swap, a deposit txid — so the
|
|
3274
|
+
// most keep-worthy screen gets copy buttons and
|
|
3275
|
+
// explorer links, not un-copyable text. No
|
|
3276
|
+
// `decodeLinkUrl` is passed, so the bolt11 never
|
|
3277
|
+
// reaches a third party.
|
|
3278
|
+
state: checkoutModel,
|
|
3279
|
+
className: classNames?.details,
|
|
3280
|
+
onError
|
|
3281
|
+
}) : expired ? React10.createElement(
|
|
3282
|
+
"div",
|
|
3283
|
+
{
|
|
3284
|
+
key: "expired-actions",
|
|
3285
|
+
className: joinClassNames(orClasses7.actions, classNames?.actions),
|
|
3286
|
+
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.actions]: ""
|
|
3287
|
+
},
|
|
3288
|
+
React10.createElement(
|
|
3289
|
+
ButtonComponent ?? "button",
|
|
3290
|
+
{
|
|
3291
|
+
type: "button",
|
|
3292
|
+
className: orClasses7.btn,
|
|
3293
|
+
onClick: startOver
|
|
3294
|
+
},
|
|
3295
|
+
checkoutLabels6.startOver
|
|
3296
|
+
)
|
|
3297
|
+
) : React10.createElement(
|
|
3298
|
+
"div",
|
|
3159
3299
|
{
|
|
3160
|
-
key: "
|
|
3161
|
-
className: orClasses7.
|
|
3162
|
-
|
|
3163
|
-
rel: "noreferrer",
|
|
3164
|
-
target: "_blank"
|
|
3300
|
+
key: "actions",
|
|
3301
|
+
className: joinClassNames(orClasses7.actions, classNames?.actions),
|
|
3302
|
+
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.actions]: ""
|
|
3165
3303
|
},
|
|
3166
|
-
|
|
3304
|
+
React10.createElement(CopyButton, {
|
|
3305
|
+
key: "copy-invoice",
|
|
3306
|
+
invoice: checkoutModel.invoice,
|
|
3307
|
+
copyInvoice: checkoutModel.copyInvoice,
|
|
3308
|
+
onError,
|
|
3309
|
+
logger,
|
|
3310
|
+
ButtonComponent,
|
|
3311
|
+
className: classNames?.copyButton
|
|
3312
|
+
}),
|
|
3313
|
+
// Opt-in slot: the default checkout ships no wallet button, so a
|
|
3314
|
+
// desktop payer is never sent to a handler that does not exist.
|
|
3315
|
+
OpenWalletButtonComponent === void 0 ? null : React10.createElement(OpenWalletButtonComponent, {
|
|
3316
|
+
key: "open-wallet",
|
|
3317
|
+
invoice: checkoutModel.invoice,
|
|
3318
|
+
openWallet: checkoutModel.openWallet,
|
|
3319
|
+
onError,
|
|
3320
|
+
logger,
|
|
3321
|
+
ButtonComponent,
|
|
3322
|
+
className: classNames?.openWalletButton
|
|
3323
|
+
}),
|
|
3324
|
+
decodeInvoiceHref === void 0 ? null : React10.createElement(
|
|
3325
|
+
"a",
|
|
3326
|
+
{
|
|
3327
|
+
key: "decode-invoice",
|
|
3328
|
+
className: orClasses7.btn,
|
|
3329
|
+
href: decodeInvoiceHref,
|
|
3330
|
+
rel: "noreferrer",
|
|
3331
|
+
target: "_blank"
|
|
3332
|
+
},
|
|
3333
|
+
checkoutLabels6.decodeInvoice
|
|
3334
|
+
)
|
|
3167
3335
|
)
|
|
3168
3336
|
)
|
|
3169
|
-
)
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
]
|
|
3337
|
+
),
|
|
3338
|
+
paymentWizard && !settled && (!expired || swapFocused) ? React10.createElement(PaymentWizard, {
|
|
3339
|
+
key: "wizard",
|
|
3340
|
+
// Only pass invoice when it's a real bolt11 (non-empty, non-deferred).
|
|
3341
|
+
invoice: checkoutModel.invoice || void 0,
|
|
3342
|
+
checkout: checkoutModel.checkout,
|
|
3343
|
+
className: classNames?.wizard,
|
|
3344
|
+
logger,
|
|
3345
|
+
onError,
|
|
3346
|
+
onSwapFocusChange: setSwapFocused,
|
|
3347
|
+
prefix,
|
|
3348
|
+
qrEncoder,
|
|
3349
|
+
decodeLinkUrl,
|
|
3350
|
+
logContext: getCheckoutLogContext({
|
|
3351
|
+
invoice_id: checkoutModel.invoice_id,
|
|
3352
|
+
payment_hash: checkoutModel.payment_hash,
|
|
3353
|
+
amount_msats: checkoutModel.amount_msats
|
|
3354
|
+
}),
|
|
3355
|
+
onProviderCopy,
|
|
3356
|
+
onCopy,
|
|
3357
|
+
onRequestLightning,
|
|
3358
|
+
onSwapStarted,
|
|
3359
|
+
resolveAssetUrl,
|
|
3360
|
+
assetBaseUrl,
|
|
3361
|
+
// Whether a payer who closes the tab has a URL to come back
|
|
3362
|
+
// to. Explicit wins — only the host knows about a per-order
|
|
3363
|
+
// route of its own; otherwise infer it from the two props that
|
|
3364
|
+
// put the reference in the URL.
|
|
3365
|
+
resumable: resumable ?? (syncUrl === true || routeReference !== void 0),
|
|
3366
|
+
// The engine's staged refund address rides the controller this
|
|
3367
|
+
// model owns, so a poll cannot wipe a review in progress.
|
|
3368
|
+
swapRefund: checkoutModel
|
|
3369
|
+
}) : null
|
|
3370
|
+
]
|
|
3371
|
+
]
|
|
3204
3372
|
);
|
|
3205
3373
|
}
|
|
3206
3374
|
|