@openreceive/react 0.2.4 → 0.3.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.
- package/dist/index.d.ts +29 -18
- package/dist/index.js +231 -169
- package/dist/styles.css +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -30,16 +30,23 @@ function useCheckoutSession(options) {
|
|
|
30
30
|
reference: () => optionsRef.current.reference(),
|
|
31
31
|
requestCheckout: (reference) => optionsRef.current.requestCheckout?.(reference),
|
|
32
32
|
onSnapshot: (snapshot) => optionsRef.current.onSnapshot?.(snapshot),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
// The inner `swap` is always present because the session is built once,
|
|
34
|
+
// on the first render, and the host may only gain swap options later.
|
|
35
|
+
// Every accessor reads through `optionsRef`, so a host with no `swap`
|
|
36
|
+
// makes `prefix()` answer undefined and the session reports the missing
|
|
37
|
+
// wiring instead of silently doing nothing.
|
|
38
|
+
swap: {
|
|
39
|
+
selection: {
|
|
40
|
+
started: () => optionsRef.current.swap?.selection.started(),
|
|
41
|
+
setStarted: (invoice) => optionsRef.current.swap?.selection.setStarted(invoice),
|
|
42
|
+
dismissedInvoiceId: () => optionsRef.current.swap?.selection.dismissedInvoiceId() ?? null,
|
|
43
|
+
setDismissedInvoiceId: (invoiceId) => optionsRef.current.swap?.selection.setDismissedInvoiceId(invoiceId),
|
|
44
|
+
setSelectedAsset: (payInAsset) => optionsRef.current.swap?.selection.setSelectedAsset(payInAsset)
|
|
45
|
+
},
|
|
46
|
+
prefix: () => optionsRef.current.swap?.prefix(),
|
|
47
|
+
fetch: () => optionsRef.current.swap?.fetch(),
|
|
48
|
+
onStarted: (invoice) => optionsRef.current.swap?.onStarted?.(invoice)
|
|
41
49
|
},
|
|
42
|
-
onSwapStarted: (invoice) => optionsRef.current.onSwapStarted?.(invoice),
|
|
43
50
|
get logger() {
|
|
44
51
|
return optionsRef.current.logger;
|
|
45
52
|
},
|
|
@@ -56,8 +63,7 @@ import {
|
|
|
56
63
|
OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES,
|
|
57
64
|
copyInvoice as copyInvoiceHelper,
|
|
58
65
|
createCheckoutStatusModel,
|
|
59
|
-
|
|
60
|
-
createQrSvg,
|
|
66
|
+
createQrSvgController,
|
|
61
67
|
formatAmountCaption,
|
|
62
68
|
checkoutLabels,
|
|
63
69
|
openWallet as openWalletHelper,
|
|
@@ -186,14 +192,15 @@ function QRCode(props) {
|
|
|
186
192
|
const onErrorRef = React3.useRef(onError);
|
|
187
193
|
onErrorRef.current = onError;
|
|
188
194
|
React3.useEffect(() => {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
195
|
+
const controller = createQrSvgController({
|
|
196
|
+
onValue: setSvg,
|
|
197
|
+
onError: (error) => onErrorRef.current?.(error),
|
|
198
|
+
...encoder === void 0 ? {} : { encoder },
|
|
199
|
+
width
|
|
194
200
|
});
|
|
201
|
+
controller.show(invoice);
|
|
195
202
|
return () => {
|
|
196
|
-
|
|
203
|
+
controller.stop();
|
|
197
204
|
};
|
|
198
205
|
}, [invoice, encoder, width]);
|
|
199
206
|
return React3.createElement("div", {
|
|
@@ -320,31 +327,6 @@ function SettledCheckIcon() {
|
|
|
320
327
|
})
|
|
321
328
|
);
|
|
322
329
|
}
|
|
323
|
-
function PaymentData(props) {
|
|
324
|
-
const entries = createPaymentDataEntries(props.source);
|
|
325
|
-
if (entries.length === 0) return null;
|
|
326
|
-
return React3.createElement(
|
|
327
|
-
"details",
|
|
328
|
-
{ className: joinClassNames(orClasses.paymentData, props.className) },
|
|
329
|
-
React3.createElement(
|
|
330
|
-
"summary",
|
|
331
|
-
{ className: orClasses.paymentDataTitle },
|
|
332
|
-
checkoutLabels.viewPaymentData
|
|
333
|
-
),
|
|
334
|
-
React3.createElement(
|
|
335
|
-
"div",
|
|
336
|
-
{ className: orClasses.paymentDataBody },
|
|
337
|
-
entries.map(
|
|
338
|
-
(entry) => React3.createElement(
|
|
339
|
-
"div",
|
|
340
|
-
{ key: entry.label, className: orClasses.paymentDataRow },
|
|
341
|
-
React3.createElement("span", { className: orClasses.paymentDataKey }, entry.label),
|
|
342
|
-
React3.createElement("p", { className: orClasses.paymentDataValue }, entry.value)
|
|
343
|
-
)
|
|
344
|
-
)
|
|
345
|
-
)
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
330
|
function WaitingState(props) {
|
|
349
331
|
const status = props.status ?? createCheckoutStatusModel({
|
|
350
332
|
phase: props.phase,
|
|
@@ -872,6 +854,38 @@ function useCheckout(options) {
|
|
|
872
854
|
const next = controllerRef.current?.cancel();
|
|
873
855
|
if (next !== void 0) setState(next);
|
|
874
856
|
}, []);
|
|
857
|
+
const swapRefundController = React6.useCallback(() => {
|
|
858
|
+
const controller = controllerRef.current;
|
|
859
|
+
if (controller === null) {
|
|
860
|
+
throw new Error("Swap refunds need a started checkout controller.");
|
|
861
|
+
}
|
|
862
|
+
return controller;
|
|
863
|
+
}, []);
|
|
864
|
+
const stageSwapRefund = React6.useCallback(
|
|
865
|
+
async (refund) => {
|
|
866
|
+
try {
|
|
867
|
+
return await swapRefundController().stageSwapRefund(refund);
|
|
868
|
+
} catch (error) {
|
|
869
|
+
onErrorRef.current?.(error);
|
|
870
|
+
throw error;
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
[swapRefundController]
|
|
874
|
+
);
|
|
875
|
+
const confirmSwapRefund = React6.useCallback(
|
|
876
|
+
async (refund) => {
|
|
877
|
+
try {
|
|
878
|
+
return await swapRefundController().confirmSwapRefund(refund);
|
|
879
|
+
} catch (error) {
|
|
880
|
+
onErrorRef.current?.(error);
|
|
881
|
+
throw error;
|
|
882
|
+
}
|
|
883
|
+
},
|
|
884
|
+
[swapRefundController]
|
|
885
|
+
);
|
|
886
|
+
const clearSwapRefundStaging = React6.useCallback(() => {
|
|
887
|
+
controllerRef.current?.clearSwapRefundStaging();
|
|
888
|
+
}, []);
|
|
875
889
|
return {
|
|
876
890
|
// The state IS the view model now: one derivation, one set of display
|
|
877
891
|
// fields. `status` stays on top of it because the component's terminal
|
|
@@ -890,7 +904,10 @@ function useCheckout(options) {
|
|
|
890
904
|
retry,
|
|
891
905
|
cancel,
|
|
892
906
|
copyInvoice,
|
|
893
|
-
openWallet
|
|
907
|
+
openWallet,
|
|
908
|
+
stageSwapRefund,
|
|
909
|
+
confirmSwapRefund,
|
|
910
|
+
clearSwapRefundStaging
|
|
894
911
|
};
|
|
895
912
|
}
|
|
896
913
|
var CheckoutContext = React6.createContext(null);
|
|
@@ -914,12 +931,12 @@ import {
|
|
|
914
931
|
buildMethodGridEntries,
|
|
915
932
|
checkoutLabels as checkoutLabels5,
|
|
916
933
|
copyInvoice as copyInvoiceHelper3,
|
|
934
|
+
createAssetBaseUrlResolver,
|
|
935
|
+
createMethodGridDisplay,
|
|
917
936
|
createPaymentWizardController,
|
|
918
937
|
createPaymentWizardModel,
|
|
919
938
|
createWizardRouteAssetDisplays,
|
|
920
939
|
createWizardRouteDisplays,
|
|
921
|
-
findSwapGridGroup,
|
|
922
|
-
formatChooseNetworkHeading,
|
|
923
940
|
formatNetworkSummary,
|
|
924
941
|
getNetworkIcon,
|
|
925
942
|
getPaymentMethodIcon,
|
|
@@ -930,16 +947,12 @@ import {
|
|
|
930
947
|
networkMobileRevealClasses,
|
|
931
948
|
networkSummaryIconClasses,
|
|
932
949
|
orClasses as orClasses6,
|
|
933
|
-
overlaySwapRefundStaging,
|
|
934
|
-
paymentAccentId,
|
|
935
950
|
paymentMethods,
|
|
951
|
+
resolveWizardSelection,
|
|
936
952
|
requestSwapRefund,
|
|
953
|
+
selectCurrentSwapInvoice,
|
|
937
954
|
swapAssetMatchesRoute,
|
|
938
|
-
|
|
939
|
-
swapOptionLimitMessage as swapOptionLimitMessage2,
|
|
940
|
-
swapPickerKey,
|
|
941
|
-
updateSelectedSwapNetworks,
|
|
942
|
-
wizardNetworkGroupIds
|
|
955
|
+
swapOptionLimitMessage as swapOptionLimitMessage2
|
|
943
956
|
} from "@openreceive/browser/headless";
|
|
944
957
|
import * as React9 from "react";
|
|
945
958
|
|
|
@@ -1189,7 +1202,7 @@ import {
|
|
|
1189
1202
|
createDetailExternalLink,
|
|
1190
1203
|
createSwapDisplayModel,
|
|
1191
1204
|
createTransactionDetails,
|
|
1192
|
-
|
|
1205
|
+
createQrSvgController as createQrSvgController2,
|
|
1193
1206
|
getSwapRefundFormError,
|
|
1194
1207
|
checkoutLabels as checkoutLabels4,
|
|
1195
1208
|
createSwapUnavailableModel,
|
|
@@ -1296,12 +1309,11 @@ function renderSwapUnavailable(quote, checkout) {
|
|
|
1296
1309
|
);
|
|
1297
1310
|
}
|
|
1298
1311
|
function renderSwapDepositPanel(options) {
|
|
1299
|
-
const display = createSwapDisplayModel(
|
|
1300
|
-
options.
|
|
1301
|
-
options.
|
|
1302
|
-
);
|
|
1312
|
+
const display = createSwapDisplayModel(options.invoice, {
|
|
1313
|
+
...options.now === void 0 ? {} : { now: options.now },
|
|
1314
|
+
...options.resumable === void 0 ? {} : { resumable: options.resumable }
|
|
1315
|
+
});
|
|
1303
1316
|
if (display === void 0) return null;
|
|
1304
|
-
const memo = display.depositMemo;
|
|
1305
1317
|
const backButton = React8.createElement(
|
|
1306
1318
|
"button",
|
|
1307
1319
|
{
|
|
@@ -1450,7 +1462,7 @@ function renderSwapDepositPanel(options) {
|
|
|
1450
1462
|
onError: options.onError
|
|
1451
1463
|
}),
|
|
1452
1464
|
renderSwapSupportDetails(display, options),
|
|
1453
|
-
renderSwapRefundReturnWarning()
|
|
1465
|
+
renderSwapRefundReturnWarning(display)
|
|
1454
1466
|
);
|
|
1455
1467
|
}
|
|
1456
1468
|
if (display.state === "refund_pending" || display.state === "refunded") {
|
|
@@ -1478,7 +1490,7 @@ function renderSwapDepositPanel(options) {
|
|
|
1478
1490
|
})
|
|
1479
1491
|
),
|
|
1480
1492
|
renderSwapSupportDetails(display, options),
|
|
1481
|
-
renderSwapRefundReturnWarning()
|
|
1493
|
+
renderSwapRefundReturnWarning(display)
|
|
1482
1494
|
);
|
|
1483
1495
|
}
|
|
1484
1496
|
if (display.state === "deposit") {
|
|
@@ -1517,16 +1529,14 @@ function renderSwapDepositPanel(options) {
|
|
|
1517
1529
|
{
|
|
1518
1530
|
className: orClasses5.swapDetails
|
|
1519
1531
|
},
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
memo === void 0 ? null : renderSwapCopyRow("Memo", memo, options),
|
|
1529
|
-
renderSwapCopyRow("Amount", display.depositAmount, { ...options, selectable: true })
|
|
1532
|
+
...display.copyRows.flatMap(
|
|
1533
|
+
(row) => renderSwapCopyRow(
|
|
1534
|
+
row.label,
|
|
1535
|
+
row.copyValue ?? row.value,
|
|
1536
|
+
{ ...options, selectable: row.selectable },
|
|
1537
|
+
row.value
|
|
1538
|
+
)
|
|
1539
|
+
)
|
|
1530
1540
|
),
|
|
1531
1541
|
waitingCard(display.countdownLabel),
|
|
1532
1542
|
renderSwapFeeBreakdown(display.feeBreakdown)
|
|
@@ -1740,13 +1750,13 @@ function renderSwapSupportDetails(display, options) {
|
|
|
1740
1750
|
)
|
|
1741
1751
|
);
|
|
1742
1752
|
}
|
|
1743
|
-
function renderSwapRefundReturnWarning() {
|
|
1753
|
+
function renderSwapRefundReturnWarning(display) {
|
|
1744
1754
|
return React8.createElement(
|
|
1745
1755
|
"p",
|
|
1746
1756
|
{
|
|
1747
1757
|
className: orClasses5.swapWarning
|
|
1748
1758
|
},
|
|
1749
|
-
|
|
1759
|
+
display.refundReturnLabel
|
|
1750
1760
|
);
|
|
1751
1761
|
}
|
|
1752
1762
|
var REFUND_ADDRESS_DRAFT_LIMIT = 8;
|
|
@@ -1843,17 +1853,19 @@ function SwapPayloadQRCode(props) {
|
|
|
1843
1853
|
const [svg, setSvg] = React8.useState("");
|
|
1844
1854
|
const onErrorRef = React8.useRef(props.onError);
|
|
1845
1855
|
onErrorRef.current = props.onError;
|
|
1856
|
+
const { payload, encoder } = props;
|
|
1846
1857
|
React8.useEffect(() => {
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1858
|
+
const controller = createQrSvgController2({
|
|
1859
|
+
onValue: setSvg,
|
|
1860
|
+
onError: (error) => onErrorRef.current?.(error),
|
|
1861
|
+
...encoder === void 0 ? {} : { encoder },
|
|
1862
|
+
width: 220
|
|
1852
1863
|
});
|
|
1864
|
+
controller.showPayload(payload);
|
|
1853
1865
|
return () => {
|
|
1854
|
-
|
|
1866
|
+
controller.stop();
|
|
1855
1867
|
};
|
|
1856
|
-
}, [
|
|
1868
|
+
}, [payload, encoder]);
|
|
1857
1869
|
const imageSource = svg.length === 0 ? void 0 : `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
1858
1870
|
return React8.createElement("img", {
|
|
1859
1871
|
alt: "",
|
|
@@ -1871,9 +1883,7 @@ function PaymentWizard(props) {
|
|
|
1871
1883
|
const [startedSwapInvoice, setStartedSwapInvoice] = React9.useState(null);
|
|
1872
1884
|
const [dismissedSwapInvoiceId, setDismissedSwapInvoiceId] = React9.useState(null);
|
|
1873
1885
|
const [selectedSwapAsset, setSelectedSwapAsset] = React9.useState(null);
|
|
1874
|
-
const [
|
|
1875
|
-
{}
|
|
1876
|
-
);
|
|
1886
|
+
const [selectedSwapAssetByGroup, setSelectedSwapAssetByGroup] = React9.useState({});
|
|
1877
1887
|
const [selectedPickerKey, setSelectedPickerKey] = React9.useState(null);
|
|
1878
1888
|
const autoSwapAttemptedRef = React9.useRef(/* @__PURE__ */ new Set());
|
|
1879
1889
|
const fetcher = props.fetch ?? globalThis.fetch;
|
|
@@ -1882,16 +1892,18 @@ function PaymentWizard(props) {
|
|
|
1882
1892
|
const session = useCheckoutSession({
|
|
1883
1893
|
snapshot: () => checkout,
|
|
1884
1894
|
reference: () => reference,
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1895
|
+
swap: {
|
|
1896
|
+
selection: {
|
|
1897
|
+
started: () => startedSwapInvoice ?? void 0,
|
|
1898
|
+
setStarted: setStartedSwapInvoice,
|
|
1899
|
+
dismissedInvoiceId: () => dismissedSwapInvoiceId,
|
|
1900
|
+
setDismissedInvoiceId: setDismissedSwapInvoiceId,
|
|
1901
|
+
setSelectedAsset: setSelectedSwapAsset
|
|
1902
|
+
},
|
|
1903
|
+
prefix: () => props.prefix,
|
|
1904
|
+
fetch: () => fetcher,
|
|
1905
|
+
onStarted: (invoice) => props.onSwapStarted?.(invoice)
|
|
1893
1906
|
},
|
|
1894
|
-
onSwapStarted: (invoice) => props.onSwapStarted?.(invoice),
|
|
1895
1907
|
...props.logger === void 0 ? {} : { logger: props.logger },
|
|
1896
1908
|
onError: (error) => props.onError?.(error)
|
|
1897
1909
|
});
|
|
@@ -1899,9 +1911,10 @@ function PaymentWizard(props) {
|
|
|
1899
1911
|
const clearSwapFocus = React9.useCallback(() => {
|
|
1900
1912
|
setSelectedSwapAsset(null);
|
|
1901
1913
|
setSelectedPickerKey(null);
|
|
1902
|
-
|
|
1914
|
+
setSelectedSwapAssetByGroup({});
|
|
1903
1915
|
session.clearSwapStartError();
|
|
1904
|
-
|
|
1916
|
+
props.swapRefund?.clearSwapRefundStaging();
|
|
1917
|
+
}, [session, props.swapRefund]);
|
|
1905
1918
|
const onSwapFocusChange = props.onSwapFocusChange;
|
|
1906
1919
|
React9.useEffect(() => {
|
|
1907
1920
|
onSwapFocusChange?.(selectedSwapAsset !== null);
|
|
@@ -1912,7 +1925,10 @@ function PaymentWizard(props) {
|
|
|
1912
1925
|
return { enabled: methods.length > 0, options: methods };
|
|
1913
1926
|
}, [checkout]);
|
|
1914
1927
|
const currentSwapInvoice = React9.useMemo(
|
|
1915
|
-
() => selectCurrentSwapInvoice(checkout,
|
|
1928
|
+
() => selectCurrentSwapInvoice(checkout, {
|
|
1929
|
+
started: startedSwapInvoice,
|
|
1930
|
+
dismissedInvoiceId: dismissedSwapInvoiceId
|
|
1931
|
+
}),
|
|
1916
1932
|
[checkout, startedSwapInvoice, dismissedSwapInvoiceId]
|
|
1917
1933
|
);
|
|
1918
1934
|
const now = useTickingUnixSeconds(currentSwapInvoice !== void 0);
|
|
@@ -1925,6 +1941,7 @@ function PaymentWizard(props) {
|
|
|
1925
1941
|
},
|
|
1926
1942
|
[props.prefix, session]
|
|
1927
1943
|
);
|
|
1944
|
+
const swapRefund = props.swapRefund;
|
|
1928
1945
|
const refundSwap = React9.useCallback(
|
|
1929
1946
|
async (attemptId, refundAddress, confirm) => {
|
|
1930
1947
|
const prefix = props.prefix;
|
|
@@ -1932,12 +1949,17 @@ function PaymentWizard(props) {
|
|
|
1932
1949
|
return;
|
|
1933
1950
|
}
|
|
1934
1951
|
try {
|
|
1935
|
-
const invoice = await
|
|
1952
|
+
const invoice = swapRefund !== void 0 ? await (confirm ? swapRefund.confirmSwapRefund : swapRefund.stageSwapRefund).call(
|
|
1953
|
+
swapRefund,
|
|
1954
|
+
{ attemptId, refundAddress }
|
|
1955
|
+
) : await requestSwapRefund({
|
|
1936
1956
|
fetch: fetcher,
|
|
1937
1957
|
prefix,
|
|
1938
1958
|
reference,
|
|
1939
|
-
|
|
1940
|
-
|
|
1959
|
+
paymentHash: resolveAttemptPaymentHash(
|
|
1960
|
+
[startedSwapInvoice, ...checkout?.invoices ?? []],
|
|
1961
|
+
attemptId
|
|
1962
|
+
),
|
|
1941
1963
|
refundAddress,
|
|
1942
1964
|
confirm,
|
|
1943
1965
|
...props.logger === void 0 ? {} : { logger: props.logger }
|
|
@@ -1954,6 +1976,7 @@ function PaymentWizard(props) {
|
|
|
1954
1976
|
fetcher,
|
|
1955
1977
|
props.onError,
|
|
1956
1978
|
props.logger,
|
|
1979
|
+
swapRefund,
|
|
1957
1980
|
startedSwapInvoice,
|
|
1958
1981
|
checkout?.invoices
|
|
1959
1982
|
]
|
|
@@ -1966,12 +1989,13 @@ function PaymentWizard(props) {
|
|
|
1966
1989
|
);
|
|
1967
1990
|
const model = createPaymentWizardModel(selection);
|
|
1968
1991
|
const { wizard } = model;
|
|
1992
|
+
const resolveAssetUrl = props.resolveAssetUrl ?? (props.assetBaseUrl === void 0 || props.assetBaseUrl.trim() === "" ? void 0 : createAssetBaseUrlResolver(props.assetBaseUrl));
|
|
1969
1993
|
const routeAssetDisplays = createWizardRouteAssetDisplays(model.routeAssets, {
|
|
1970
1994
|
selectedRoute: model.selectedRoute,
|
|
1971
|
-
...
|
|
1995
|
+
...resolveAssetUrl === void 0 ? {} : { resolveAssetUrl }
|
|
1972
1996
|
});
|
|
1973
1997
|
const routeDisplays = createWizardRouteDisplays(wizard.routes, {
|
|
1974
|
-
...
|
|
1998
|
+
...resolveAssetUrl === void 0 ? {} : { resolveAssetUrl }
|
|
1975
1999
|
});
|
|
1976
2000
|
const showRoutePicker = routeAssetDisplays.length > 0 && (model.selectedRoute === null || routeDisplays.length === 0);
|
|
1977
2001
|
const activeTutorialProvider = activeTutorial === null ? void 0 : routeDisplays.flatMap((route) => route.providers).find((provider) => provider.id === activeTutorial.providerId);
|
|
@@ -2024,6 +2048,7 @@ function PaymentWizard(props) {
|
|
|
2024
2048
|
logger: props.logger,
|
|
2025
2049
|
onError: props.onError,
|
|
2026
2050
|
onRefund: refundSwap,
|
|
2051
|
+
...props.resumable === void 0 ? {} : { resumable: props.resumable },
|
|
2027
2052
|
onBackToLightning: () => {
|
|
2028
2053
|
setDismissedSwapInvoiceId(activeSwapForAsset.invoice_id);
|
|
2029
2054
|
clearSwapFocus();
|
|
@@ -2047,21 +2072,37 @@ function PaymentWizard(props) {
|
|
|
2047
2072
|
checkout: checkout ?? void 0,
|
|
2048
2073
|
selectedPickerKey,
|
|
2049
2074
|
startingAsset: swapStartingAsset,
|
|
2050
|
-
|
|
2075
|
+
selectedSwapAssetByGroup,
|
|
2076
|
+
// One resolver decides what a tile click MEANS, so the "ask the
|
|
2077
|
+
// network question only when it is a real question" rule is not
|
|
2078
|
+
// re-derived here: a single-network group comes back as start_swap
|
|
2079
|
+
// and the wizard starts it instead of opening a one-answer step.
|
|
2051
2080
|
onSelectPicker: (key, previousKey) => {
|
|
2081
|
+
const resolved = resolveWizardSelection({
|
|
2082
|
+
pickerKey: key,
|
|
2083
|
+
previousKey,
|
|
2084
|
+
entries: buildMethodGridEntries(paymentMethods, swapAssetOptions),
|
|
2085
|
+
selectedAssetByGroup: selectedSwapAssetByGroup
|
|
2086
|
+
});
|
|
2087
|
+
if (resolved.kind === "none") return;
|
|
2088
|
+
if (resolved.kind === "select_method") {
|
|
2089
|
+
setSelectedPickerKey(null);
|
|
2090
|
+
updateWizardSelection(
|
|
2091
|
+
(controller) => controller.selectMethod(resolved.methodId)
|
|
2092
|
+
);
|
|
2093
|
+
if (resolved.methodId === "bitcoin") void props.onRequestLightning?.();
|
|
2094
|
+
return;
|
|
2095
|
+
}
|
|
2096
|
+
if (resolved.kind === "start_swap") {
|
|
2097
|
+
setSelectedPickerKey(null);
|
|
2098
|
+
selectSwapAsset(resolved.payInAsset);
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
2052
2101
|
setSelectedPickerKey(key);
|
|
2053
|
-
|
|
2054
|
-
setSelectedSwapNetworks(
|
|
2055
|
-
(current) => updateSelectedSwapNetworks({
|
|
2056
|
-
entries,
|
|
2057
|
-
nextKey: key,
|
|
2058
|
-
previousKey,
|
|
2059
|
-
selectedNetworks: current
|
|
2060
|
-
})
|
|
2061
|
-
);
|
|
2102
|
+
setSelectedSwapAssetByGroup(resolved.selectedAssetByGroup);
|
|
2062
2103
|
},
|
|
2063
2104
|
onSelectNetwork: (groupKey, payInAsset) => {
|
|
2064
|
-
|
|
2105
|
+
setSelectedSwapAssetByGroup((current) => ({
|
|
2065
2106
|
...current,
|
|
2066
2107
|
[groupKey]: payInAsset
|
|
2067
2108
|
}));
|
|
@@ -2075,7 +2116,7 @@ function PaymentWizard(props) {
|
|
|
2075
2116
|
}
|
|
2076
2117
|
},
|
|
2077
2118
|
onContinueSwap: selectSwapAsset,
|
|
2078
|
-
...
|
|
2119
|
+
...resolveAssetUrl === void 0 ? {} : { resolveAssetUrl }
|
|
2079
2120
|
}) : null,
|
|
2080
2121
|
selection.selectedMethod === null ? null : React9.createElement(
|
|
2081
2122
|
"div",
|
|
@@ -2144,6 +2185,7 @@ function PaymentWizard(props) {
|
|
|
2144
2185
|
logger: props.logger,
|
|
2145
2186
|
onError: props.onError,
|
|
2146
2187
|
onRefund: refundSwap,
|
|
2188
|
+
...props.resumable === void 0 ? {} : { resumable: props.resumable },
|
|
2147
2189
|
onBackToLightning: () => {
|
|
2148
2190
|
setDismissedSwapInvoiceId(activeSwapForRoute.invoice_id);
|
|
2149
2191
|
clearSwapFocus();
|
|
@@ -2242,23 +2284,16 @@ function PaymentWizard(props) {
|
|
|
2242
2284
|
);
|
|
2243
2285
|
}
|
|
2244
2286
|
function renderCompactPaymentMethodSelector(options) {
|
|
2245
|
-
const
|
|
2287
|
+
const display = createMethodGridDisplay({
|
|
2288
|
+
entries: buildMethodGridEntries(paymentMethods, options.swapAssetOptions),
|
|
2289
|
+
selectedPickerKey: options.selectedPickerKey,
|
|
2290
|
+
selectedAssetByGroup: options.selectedSwapAssetByGroup,
|
|
2291
|
+
startingAsset: options.startingAsset,
|
|
2292
|
+
...options.checkout === void 0 ? {} : { checkout: options.checkout }
|
|
2293
|
+
});
|
|
2246
2294
|
const currenciesLoading = options.currenciesLoading === true && options.swapAssetOptions.length === 0;
|
|
2247
|
-
const
|
|
2248
|
-
const
|
|
2249
|
-
const networkRequired = selectedGroup !== void 0 && selectedGroup.options.length > 1;
|
|
2250
|
-
const selectedGroupKey = selectedGroup?.label.trim().toUpperCase();
|
|
2251
|
-
const selectedNetworkAsset = selectedGroupKey === void 0 ? void 0 : options.selectedSwapNetworks[selectedGroupKey];
|
|
2252
|
-
const selectedNetworkOption = selectedGroup === void 0 || selectedNetworkAsset === void 0 ? void 0 : selectedGroup.options.find((option) => option.pay_in_asset === selectedNetworkAsset);
|
|
2253
|
-
const continueTarget = selectedNetworkOption !== void 0 ? {
|
|
2254
|
-
payInAsset: selectedNetworkOption.pay_in_asset,
|
|
2255
|
-
disabled: selectedNetworkOption.available === false,
|
|
2256
|
-
limitMessage: swapOptionLimitMessage2(selectedNetworkOption, options.checkout)
|
|
2257
|
-
} : null;
|
|
2258
|
-
const startingAsset = options.startingAsset;
|
|
2259
|
-
const gridBusy = startingAsset !== null;
|
|
2260
|
-
const continueStarting = continueTarget !== null && continueTarget.payInAsset === startingAsset;
|
|
2261
|
-
const canContinue = continueTarget !== null && !continueTarget.disabled && selectedNetworkOption !== void 0 && !gridBusy;
|
|
2295
|
+
const { gridBusy, networkRequired, selectedGroup, continueTarget, canContinue } = display;
|
|
2296
|
+
const continueStarting = continueTarget?.starting === true;
|
|
2262
2297
|
const continueButton = (className) => React9.createElement(
|
|
2263
2298
|
"button",
|
|
2264
2299
|
{
|
|
@@ -2268,7 +2303,7 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2268
2303
|
"aria-disabled": canContinue ? void 0 : "true",
|
|
2269
2304
|
"aria-busy": continueStarting ? "true" : void 0,
|
|
2270
2305
|
onClick: !canContinue ? void 0 : () => {
|
|
2271
|
-
if (continueTarget ===
|
|
2306
|
+
if (continueTarget === void 0) return;
|
|
2272
2307
|
options.onContinueSwap(continueTarget.payInAsset);
|
|
2273
2308
|
}
|
|
2274
2309
|
},
|
|
@@ -2280,14 +2315,10 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2280
2315
|
"aria-hidden": "true"
|
|
2281
2316
|
}),
|
|
2282
2317
|
checkoutLabels5.preparingPayment
|
|
2283
|
-
) : continueTarget?.
|
|
2318
|
+
) : continueTarget?.label ?? checkoutLabels5.continue
|
|
2284
2319
|
);
|
|
2285
2320
|
const renderNetworkSelector = (group, mobile) => {
|
|
2286
|
-
const accent =
|
|
2287
|
-
const groupKey = group.label.trim().toUpperCase();
|
|
2288
|
-
const selectedAsset = options.selectedSwapNetworks[groupKey];
|
|
2289
|
-
const selectedOption = selectedAsset === void 0 ? void 0 : group.options.find((option) => option.pay_in_asset === selectedAsset);
|
|
2290
|
-
const { panelId, headingId } = wizardNetworkGroupIds(groupKey);
|
|
2321
|
+
const { accent, groupKey, panelId, headingId, selectedOption } = group;
|
|
2291
2322
|
return React9.createElement(
|
|
2292
2323
|
"div",
|
|
2293
2324
|
{
|
|
@@ -2308,7 +2339,7 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2308
2339
|
id: headingId,
|
|
2309
2340
|
className: orClasses6.methodNetworkHeading
|
|
2310
2341
|
},
|
|
2311
|
-
|
|
2342
|
+
group.heading
|
|
2312
2343
|
),
|
|
2313
2344
|
React9.createElement(
|
|
2314
2345
|
"p",
|
|
@@ -2422,23 +2453,22 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2422
2453
|
"aria-label": checkoutLabels5.paymentMethod,
|
|
2423
2454
|
className: orClasses6.methodGrid
|
|
2424
2455
|
},
|
|
2425
|
-
...entries.map((entry) => {
|
|
2456
|
+
...display.entries.map((entry) => {
|
|
2426
2457
|
if (entry.kind === "method") {
|
|
2427
2458
|
const method = entry.method;
|
|
2428
|
-
const accent2 = paymentAccentId(method.id);
|
|
2429
2459
|
return React9.createElement(
|
|
2430
2460
|
"button",
|
|
2431
2461
|
{
|
|
2432
2462
|
key: method.id,
|
|
2433
2463
|
type: "button",
|
|
2434
2464
|
className: assetButtonClasses({
|
|
2435
|
-
accent:
|
|
2465
|
+
accent: entry.accent,
|
|
2436
2466
|
selected: false,
|
|
2437
|
-
disabled:
|
|
2467
|
+
disabled: entry.disabled
|
|
2438
2468
|
}),
|
|
2439
|
-
disabled:
|
|
2440
|
-
"aria-disabled":
|
|
2441
|
-
onClick:
|
|
2469
|
+
disabled: entry.disabled,
|
|
2470
|
+
"aria-disabled": entry.disabled ? "true" : void 0,
|
|
2471
|
+
onClick: entry.disabled ? void 0 : () => options.onContinueMethod(method.id)
|
|
2442
2472
|
},
|
|
2443
2473
|
React9.createElement(
|
|
2444
2474
|
"span",
|
|
@@ -2457,21 +2487,18 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2457
2487
|
);
|
|
2458
2488
|
}
|
|
2459
2489
|
const group = entry.group;
|
|
2460
|
-
const
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
const limitOption = disabled ? swapGroupLimitOption(group.options) ?? activeOption : activeOption;
|
|
2473
|
-
const limitMessage = swapOptionLimitMessage2(limitOption, options.checkout);
|
|
2474
|
-
const { panelId } = wizardNetworkGroupIds(groupKey);
|
|
2490
|
+
const {
|
|
2491
|
+
pickerKey,
|
|
2492
|
+
selected,
|
|
2493
|
+
multiNetwork,
|
|
2494
|
+
displayOption,
|
|
2495
|
+
selectedOption,
|
|
2496
|
+
starting,
|
|
2497
|
+
disabled,
|
|
2498
|
+
accent,
|
|
2499
|
+
limitMessage,
|
|
2500
|
+
panelId
|
|
2501
|
+
} = group;
|
|
2475
2502
|
return React9.createElement(
|
|
2476
2503
|
"div",
|
|
2477
2504
|
{ key: pickerKey, className: orClasses6.methodTile },
|
|
@@ -2490,7 +2517,14 @@ function renderCompactPaymentMethodSelector(options) {
|
|
|
2490
2517
|
selected: starting || multiNetwork && selected,
|
|
2491
2518
|
disabled: disabled || gridBusy && !starting
|
|
2492
2519
|
}),
|
|
2493
|
-
onClick: disabled || gridBusy ? void 0 :
|
|
2520
|
+
onClick: disabled || gridBusy ? void 0 : (
|
|
2521
|
+
// `needsNetworkStep` / `startPayInAsset` are the
|
|
2522
|
+
// options.length > 1 rule as DATA, so neither renderer
|
|
2523
|
+
// re-derives which of the two a tile click means.
|
|
2524
|
+
group.needsNetworkStep ? () => options.onSelectPicker(pickerKey, options.selectedPickerKey) : () => options.onContinueSwap(
|
|
2525
|
+
group.startPayInAsset ?? displayOption.pay_in_asset
|
|
2526
|
+
)
|
|
2527
|
+
)
|
|
2494
2528
|
},
|
|
2495
2529
|
React9.createElement(
|
|
2496
2530
|
"span",
|
|
@@ -2647,13 +2681,13 @@ function renderWizardBreadcrumbs(options) {
|
|
|
2647
2681
|
function swapOptionsForRoute(routeKey, options) {
|
|
2648
2682
|
return options.filter((option) => swapAssetMatchesRoute(routeKey, option.pay_in_asset));
|
|
2649
2683
|
}
|
|
2650
|
-
function
|
|
2651
|
-
const
|
|
2652
|
-
(invoice
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2684
|
+
function resolveAttemptPaymentHash(invoices, attemptId) {
|
|
2685
|
+
for (const invoice of invoices) {
|
|
2686
|
+
if (invoice == null) continue;
|
|
2687
|
+
if ((invoice.swap?.attempt_id ?? invoice.invoice_id) !== attemptId) continue;
|
|
2688
|
+
if (invoice.payment_hash !== void 0) return invoice.payment_hash;
|
|
2689
|
+
}
|
|
2690
|
+
throw new Error(`No swap attempt ${attemptId} in this checkout.`);
|
|
2657
2691
|
}
|
|
2658
2692
|
function renderRoutePicker(options) {
|
|
2659
2693
|
return React9.createElement(
|
|
@@ -2868,9 +2902,13 @@ function CheckoutView(props) {
|
|
|
2868
2902
|
prefix = OPENRECEIVE_DEFAULT_PREFIX,
|
|
2869
2903
|
metadata: _metadata,
|
|
2870
2904
|
createFetch: _createFetch,
|
|
2871
|
-
|
|
2905
|
+
// Not `_`-prefixed like its neighbours: the view reads it, to infer
|
|
2906
|
+
// `resumable` for the refund screen. Still destructured out so it never
|
|
2907
|
+
// reaches the rendered <section>.
|
|
2908
|
+
syncUrl,
|
|
2872
2909
|
resumePathPrefix: _resumePathPrefix,
|
|
2873
|
-
routeReference
|
|
2910
|
+
routeReference,
|
|
2911
|
+
resumable,
|
|
2874
2912
|
onRequestLightning,
|
|
2875
2913
|
onSwapStarted,
|
|
2876
2914
|
mintingLightning = false,
|
|
@@ -2895,6 +2933,7 @@ function CheckoutView(props) {
|
|
|
2895
2933
|
classNames,
|
|
2896
2934
|
children,
|
|
2897
2935
|
resolveAssetUrl,
|
|
2936
|
+
assetBaseUrl,
|
|
2898
2937
|
className,
|
|
2899
2938
|
...sectionProps
|
|
2900
2939
|
} = props;
|
|
@@ -2965,6 +3004,21 @@ function CheckoutView(props) {
|
|
|
2965
3004
|
...ownsTheme ? theme.attributes : {}
|
|
2966
3005
|
},
|
|
2967
3006
|
customChildren === void 0 ? [
|
|
3007
|
+
// Above the amount and OUTSIDE the Lightning pane, which drops out on
|
|
3008
|
+
// the swap deposit panel, on expiry and on the receipt — the payer
|
|
3009
|
+
// needs to know what they are buying on all four screens.
|
|
3010
|
+
checkoutModel.checkout.description === void 0 || checkoutModel.checkout.description === "" ? null : React10.createElement(
|
|
3011
|
+
"p",
|
|
3012
|
+
{
|
|
3013
|
+
key: "order-description",
|
|
3014
|
+
className: joinClassNames(
|
|
3015
|
+
orClasses7.orderDescription,
|
|
3016
|
+
classNames?.orderDescription
|
|
3017
|
+
),
|
|
3018
|
+
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.orderDescription]: ""
|
|
3019
|
+
},
|
|
3020
|
+
checkoutModel.checkout.description
|
|
3021
|
+
),
|
|
2968
3022
|
ownsTheme ? React10.createElement(ThemeToggle, {
|
|
2969
3023
|
key: "theme",
|
|
2970
3024
|
className: classNames?.themeToggle,
|
|
@@ -3135,7 +3189,16 @@ function CheckoutView(props) {
|
|
|
3135
3189
|
onCopy,
|
|
3136
3190
|
onRequestLightning,
|
|
3137
3191
|
onSwapStarted,
|
|
3138
|
-
resolveAssetUrl
|
|
3192
|
+
resolveAssetUrl,
|
|
3193
|
+
assetBaseUrl,
|
|
3194
|
+
// Whether a payer who closes the tab has a URL to come back
|
|
3195
|
+
// to. Explicit wins — only the host knows about a per-order
|
|
3196
|
+
// route of its own; otherwise infer it from the two props that
|
|
3197
|
+
// put the reference in the URL.
|
|
3198
|
+
resumable: resumable ?? (syncUrl === true || routeReference !== void 0),
|
|
3199
|
+
// The engine's staged refund address rides the controller this
|
|
3200
|
+
// model owns, so a poll cannot wipe a review in progress.
|
|
3201
|
+
swapRefund: checkoutModel
|
|
3139
3202
|
}) : null
|
|
3140
3203
|
] : customChildren
|
|
3141
3204
|
);
|
|
@@ -3168,7 +3231,6 @@ export {
|
|
|
3168
3231
|
CopyInvoiceButton,
|
|
3169
3232
|
InvoiceSummary,
|
|
3170
3233
|
OpenWalletButton,
|
|
3171
|
-
PaymentData,
|
|
3172
3234
|
PaymentState,
|
|
3173
3235
|
PaymentWizard,
|
|
3174
3236
|
QRCode,
|